码迷,mamicode.com
首页 > 其他好文 > 详细

hdu5381 The sum of gcd

时间:2015-08-13 22:02:22      阅读:99      评论:0      收藏:0      [点我收藏+]

标签:

 

  莫队算法,预处理出每个数字往后的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 }

 

hdu5381 The sum of gcd

标签:

原文地址:http://www.cnblogs.com/fzmh/p/4728354.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!