题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5288
1 //*************头文件区************* 2 #include<iostream> 3 #include<cstdio> 4 #include<vector> 5 #define N 100010 6 #define P 1000000007 7 using namespace std; 8 int n,tmp,i,j; 9 int r[N], l[N], q[N], a[N]; 10 long long a1,a2,sum; 11 vector<int> vec[10010]; 12 int main() 13 { 14 freopen("1001.in","r",stdin); 15 freopen("m1001.out","w",stdout); 16 while(~scanf("%d",&n)){ 17 for( i = 101; i <= 10000; ++i) 18 vec[i].clear(); 19 // 清空容器 20 for( i = 1; i <= n; ++i){ 21 scanf("%d",&a[i]); 22 l[i] = 0; 23 r[i] = n+1; 24 if( a[i] > 100) 25 vec[a[i]].push_back(i); 26 // 数据初始化,超过100的数据将下标保存到vec[a[i]]内 27 } 28 for( j = 1; j <= 100; ++j){ 29 tmp = 0; 30 // 暂时保存下标 31 for( i = 1;i <= n; ++i){ 32 if( a[i] % j ==0 ) 33 l[i] = max(tmp,l[i]); 34 if( a[i] == j) 35 tmp = i; 36 } 37 tmp = n+1; 38 for( i = n;i >= 1; --i){ 39 if( a[i] % j ==0) 40 r[i] = min(tmp,r[i]); 41 if( a[i] == j) 42 tmp = i; 43 } 44 // 更新以100以内的数为约数的数的左右限制 45 } 46 47 for( i = 101; i <= 10000; ++i) 48 q[i] = vec[i].size() - 1; 49 for( i = n; i >= 1; --i){ 50 if(a[i] > 100){ 51 for( j = a[i]; j <= 10000; j = j+a[i]){ 52 while((q[j] >= 0)&&(vec[j][q[j]]>i)){ 53 l[vec[j][q[j]]] = max(l[vec[j][q[j]]],i); 54 if((q[j] > 0)&&(vec[j][q[j]-1]>i)) 55 q[j]--; 56 else 57 break; 58 } 59 } 60 } 61 } 62 for( i = 101; i <= 10000; ++i) 63 q[i] = 0; 64 // vec下标从0开始? 65 for( i = 1; i <= n; ++i) 66 if(a[i] > 100){ 67 for( j = a[i]; j <= 10000; j = j+a[i]){ 68 while((q[j]<vec[j].size())&&(vec[j][q[j]]<i)){ 69 r[vec[j][q[j]]] = min(r[vec[j][q[j]]],i); 70 if((q[j]<vec[j].size()-1)&&(vec[j][q[j]+1]<i)) 71 q[j]++; 72 else 73 break; 74 } 75 } 76 } 77 78 sum=0; 79 for (i=1;i<=n;i++) 80 { 81 a1=r[i]-i; 82 a2=i-l[i]; 83 sum=(sum+a1*a2)%P; 84 // printf("%lld\n",a1); 85 } 86 printf("%I64d\n",sum); 87 } 88 }
时间: 2024-10-12 11:40:06