HDU 5288


//枚举因子,查找和i最近的左右是i因子的点即可。

#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define LL long long using namespace std; const int MAX=100010; const LL mod=1e9+7; int l_next[10010]; int r_next[10010]; int num[MAX]; int l[MAX],r[MAX]; int main(){ int n; while(scanf("%d",&n)!=EOF){ for(int i=1;i<=n;i++){ scanf("%d",&num[i]); l[i]=0;r[i]=MAX; } for(int i=0;i<10010;i++){ l_next[i]=0; r_next[i]=MAX; } for(int i=1;i<=n;i++){ int lmax=0; for(int k=1;k*k<=num[i];k++){ if(num[i]%k==0){ lmax=max(lmax,l_next[k]); // if(k!=1) lmax=max(lmax,l_next[num[i]/k]); } } l[i]=lmax; l_next[num[i]]=i; } /* for(int i=1;i<=n;i++) cout<<l[i]<<" "; cout <<endl;*/ for(int i=n;i>=1;i--){ int rmin=n+1; for(int k=1;k*k<=num[i];k++){ if(num[i]%k==0){ rmin=min(rmin,r_next[k]); // if(k!=1) rmin=min(rmin,r_next[num[i]/k]); } } r[i]=rmin; r_next[num[i]]=i; } /* for(int i=1;i<=n;i++) cout<<r[i]<<" "; cout <<endl; */ LL ans=0; for(int i=1;i<=n;i++){ ans+=(LL)(i-l[i])*(LL)(r[i]-i); ans%=mod; } printf("%lld ",ans); } return 0; }

  

原文地址:https://www.cnblogs.com/jie-dcai/p/4796341.html