标签:
Description
Input
Output
Sample Input
Sample Output
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> using namespace std; const int maxn=10005,maxx=100005; const long long mod=1000000007; vector<int>divi[maxn]; int a[maxx],l[maxx],r[maxx],pos[maxn],n; void ini(){ for(int i=1;i<=10000;i++) for(int j=1;j<=i;j++) if(i%j==0) divi[i].push_back(j); //预处理出10000内所有数的因子 } int main(){ ini(); while(~scanf("%d",&n)){ for(int i=0;i<n;i++) scanf("%d",&a[i]); memset(l,-1,sizeof(l)); memset(r,0x3f,sizeof(r)); memset(pos,-1,sizeof(pos)); //l[i]表示a[i]左边与之最接近的它的因子的下标 for(int i=0;i<n;i++){ int lef=-1; for(int j=0;j<divi[a[i]].size();j++) lef=max(lef,pos[divi[a[i]][j]]); pos[a[i]]=i; //pos数组用于更新维护最靠近a[i]的因子数的下标 l[i]=lef; } memset(pos,0x3f,sizeof(pos)); //r[i]表示a[i]右边与之最接近的它的因子的下标 for(int i=n-1;i>=0;i--){ int rig=0x3f3f3f3f; for(int j=0;j<divi[a[i]].size();j++) rig=min(rig,pos[divi[a[i]][j]]); pos[a[i]]=i; //pos数组用于更新维护最靠近a[i]的因子数的下标 r[i]=rig; } long long ans=0,L,R; for(int i=0;i<n;i++){ if(l[i]==-1) L=i+1; //若为原值,则说明a[i]左边不存在因子 else L=i-l[i]; //否则,令L为a[i]到其因子右边第一个数之间的个数 if(r[i]==0x3f3f3f3f) R=n-i; else R=r[i]-i; ans=(L*R%mod+ans)%mod; //L*R为包含a[i]的连续区间的组合数。 } printf("%d\n",ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/names-yc/p/4665342.html