hdu5288(思维+分解因子)

来源:互联网 发布:js设置input可以编辑 编辑:程序博客网 时间:2024/04/30 10:20

链接:点击打开链接

题意:给出含n个元素的数组a,问所有区间中满足对该区间所有aj(j!=i),都使ai%aj!=0的i的个数

代码:

#include <math.h>#include <vector>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const long long MOD=1000000007;int a[100005],pos[100005],l[100005],r[100005];int main(){                                     //换种思路考虑就是每个值在那个区间会加1    int n,i,j;                                  //因此找到每个值能够整除的最近的左边界    long long ans;                              //和右边界即可,最后这个值贡献的就是    while(scanf("%d",&n)!=EOF){                 //(i-l[i])*(r[i]-i)        for(i=1;i<=n;i++)        scanf("%d",&a[i]);        memset(l,0,sizeof(l));        memset(pos,0,sizeof(pos));        for(i=1;i<=n;i++){            r[i]=n+1;            for(j=1;j<=(int)sqrt(a[i]*1.0);j++){                if(a[i]%j==0)                l[i]=max(l[i],max(pos[j],pos[a[i]/j]));            }                                   //找到左边最近出现过的因子,右边也是一样            pos[a[i]]=i;        }        for(i=1;i<=10000;i++)        pos[i]=n+1;        for(i=n;i>=1;i--){            for(j=1;j<=(int)sqrt(a[i]*1.0);j++){                if(a[i]%j==0)                r[i]=min(r[i],min(pos[j],pos[a[i]/j]));            }            pos[a[i]]=i;        }        ans=0;        for(i=1;i<=n;i++)        ans=(ans+(i-l[i])*(r[i]-i))%MOD;        printf("%I64d\n",ans);    }    return 0;}

0 0