zoukankan      html  css  js  c++  java
  • hdu5381 The sum of gcd

      莫队算法,预处理出每个数字往后的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
    ",Ans[i]);
    171     }
    172 }
  • 相关阅读:
    用户登录系统(三)
    SQL server 2005 时间函数应用 查询出结果为00:00:00 小时、分钟、秒
    Windows Server 2003系统 常用操作技巧集绵,发现了继续添加
    新一代井下数字集群通讯系统需求分析(一)
    WPF学习笔记(一)
    建立一个VSS源代码管理服务器,下面介绍建立的过程与实际应用情况
    Vista下使用VS2005的时候提示"没有安装FrontPage服务器扩展"的问题。
    SQL语句导入/导出EXCEL(转载自:白袜子blog)
    sql2005"因为它正用于复制"的错误解决办法
    (转)CS0016: 未能写入输出文件“c:\WINDOWS\xxxxxsktsuj.dll”“拒绝访问。”的处理
  • 原文地址:https://www.cnblogs.com/fzmh/p/4728354.html
Copyright © 2011-2022 走看看