标签:
莫队算法,预处理出每个数字往后的gcd情况,每个数字的gcd只可能是他的因子,因此后面最多只可能有logn种,可以先预处理出,然后套莫队算法,复杂度O(n*sqrt(n)*log(n))。
代码
1 #include<cstdio> 2 #include<cmath> 3 #include<vector> 4 #include<algorithm> 5 #define N 100000 6 using namespace std; 7 int n,q,s[N][16],i,j,tmp,l,r; 8 long long ans,Ans[N]; 9 vector<pair<int,int> > vec0[N],vec1[N]; 10 struct g 11 { 12 int l,r,t,id; 13 }Q[N]; 14 bool cmp(g a,g b) 15 { 16 if (a.t==b.t) 17 return a.r<b.r; 18 return a.t<b.t; 19 } 20 int gcd(int a,int b) 21 { 22 if (b==0) return a; 23 return gcd(b,a%b); 24 } 25 int GCD(int a,int b) 26 { 27 int k; 28 k=log2(b-a+1); 29 return gcd(s[a][k],s[b-(1<<k)+1][k]); 30 } 31 int ef(int i,int l,int r,int x) 32 { 33 int m; 34 while (l<=r) 35 { 36 m=(l+r)>>1; 37 if (GCD(i,m)==x) l=m+1;else r=m-1; 38 } 39 return l; 40 } 41 int EF(int i,int l,int r,int x) 42 { 43 int m; 44 while (l<=r) 45 { 46 m=(l+r)>>1; 47 if (GCD(m,i)==x) r=m-1;else l=m+1; 48 } 49 return r; 50 } 51 long long calc(int l,int r) 52 { 53 long long ans=0; 54 int len,t,i; 55 if (l<r) 56 { 57 len=vec0[l].size(); 58 t=l; 59 for (i=0;i<len;i++) 60 { 61 ans+=1LL*(min(r,vec0[l][i].second)-t+1)*vec0[l][i].first; 62 t=vec0[l][i].second+1; 63 if (t>r) break; 64 } 65 } 66 else 67 { 68 len=vec1[l].size(); 69 t=l; 70 for (i=0;i<len;i++) 71 { 72 ans+=1LL*(t-max(r,vec1[l][i].second)+1)*vec1[l][i].first; 73 t=vec1[l][i].second-1; 74 if (t<r) break; 75 } 76 } 77 return ans; 78 } 79 void QL() 80 { 81 while (l<Q[i].l) 82 { 83 ans-=calc(l,r); 84 l++; 85 } 86 while (l>Q[i].l) 87 { 88 l--; 89 ans+=calc(l,r); 90 } 91 } 92 void QR() 93 { 94 while (r<Q[i].r) 95 { 96 r++; 97 ans+=calc(r,l); 98 } 99 while (r>Q[i].r) 100 { 101 ans-=calc(r,l); 102 r--; 103 } 104 } 105 int main() 106 { 107 int test; 108 scanf("%d",&test); 109 while (test--) 110 { 111 scanf("%d",&n); 112 for (i=1;i<=n;i++) 113 { 114 scanf("%d",&s[i][0]); 115 vec0[i].clear(); 116 vec1[i].clear(); 117 } 118 for (i=n;i>=1;i--) 119 for (j=1;j<=log2(n);j++) 120 s[i][j]=gcd(s[i][j-1],s[i+(1<<(j-1))][j-1]); 121 122 for (i=1;i<=n;i++) 123 { 124 l=i;r=n; 125 while (l<=n) 126 { 127 tmp=GCD(i,l); 128 l=ef(i,l,r,tmp); 129 vec0[i].push_back(make_pair(tmp,l-1)); 130 } 131 } 132 133 134 for (i=n;i>=1;i--) 135 { 136 l=1;r=i; 137 while (r>0) 138 { 139 tmp=GCD(r,i); 140 r=EF(i,l,r,tmp); 141 vec1[i].push_back(make_pair(tmp,r+1)); 142 } 143 } 144 145 scanf("%d",&q); 146 for (i=1;i<=q;i++) 147 { 148 scanf("%d%d",&Q[i].l,&Q[i].r); 149 Q[i].id=i;Q[i].t=Q[i].l/100; 150 } 151 sort(Q+1,Q+1+q,cmp); 152 l=Q[1].l;r=Q[1].r;ans=0; 153 for (i=l;i<=r;i++) ans+=calc(i,r); 154 Ans[Q[1].id]=ans; 155 156 157 for (i=2;i<=q;i++) 158 { 159 if (l<Q[i].l) 160 { 161 QR();QL(); 162 } 163 else 164 { 165 QL();QR(); 166 } 167 Ans[Q[i].id]=ans; 168 } 169 for (i=1;i<=q;i++) 170 printf("%I64d\n",Ans[i]); 171 } 172 }
标签:
原文地址:http://www.cnblogs.com/fzmh/p/4728354.html