码迷,mamicode.com
首页 > 编程语言 > 详细

HDU 5381 The sum of gcd (技巧,莫队算法)

时间:2015-08-16 19:46:34      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:

 

 

 

 

 

 

  我以为稍微水一下O(n2)还是可以过的,毕竟只有3个test case。死活不让啊。

技术分享
 1 #include <bits/stdc++.h>
 2 #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
 3 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
 4 #define pii pair<int,int>
 5 #define INF 0x7f7f7f7f
 6 #define LL long long
 7 using namespace std;
 8 const int N=10005;
 9 struct node
10 {
11     int L, R, ans;
12 }que[N];
13 struct node1
14 {
15     int ll, rr, gcd;
16     node1(){};
17     node1(int ll,int rr,int gcd):ll(ll),rr(rr),gcd(gcd){};
18 }reg[N][50];
19 
20 int _gcd(int a, int b){return b == 0 ? a : _gcd(b, a % b);}
21 
22 int seq[N], n, q, pre[N];
23 int cnt[N];
24 void pre_cal()
25 {
26     memset(cnt,0,sizeof(cnt));
27     reg[n][0]=node1(n,n,seq[n]); //最后一个特殊处理
28     cnt[n]++;
29     for(int i=n-1; i>=1; i--)
30     {
31         int R=i, gcd=seq[i], tmp;
32         for(int j=0; j<cnt[i+1]; j++)
33         {
34             node1 &t=reg[i+1][j];
35             tmp=_gcd(gcd, t.gcd );
36             if(tmp!=gcd)    reg[i][cnt[i]++]=node1(i, R, gcd);
37             gcd=tmp;
38             R=t.rr;
39         }
40         reg[i][cnt[i]++]=node1(i, R, gcd);
41     }
42 }
43 
44 void cal()
45 {
46     for(int i=1; i<=n; i++)
47     {
48         pre[i-1]=0;
49         pre[i]=seq[i];
50         int p=0;
51         for(int j=i+1; j<=n; j++)
52         {
53             if(j>reg[i][p].rr)  p++;
54             pre[j]=reg[i][p].gcd;
55             pre[j]+=pre[j-1];
56         }
57         for(int j=1; j<=q; j++)
58             if( i>=que[j].L && i<=que[j].R )
59                 que[j].ans+=pre[que[j].R]-pre[i-1];
60     }
61     for(int i=1; i<=q; i++)    printf("%d\n",que[i].ans);
62 }
63 int main()
64 {
65     //freopen("input.txt", "r", stdin);
66     int t, L, R;
67     cin>>t;
68     while(t--)
69     {
70         scanf("%d", &n);
71         for(int i=1; i<=n; i++)    scanf("%d", &seq[i]);
72 
73         scanf("%d", &q);
74         for(int i=1; i<=q; i++)
75         {
76             scanf("%d %d", &que[i].L, &que[i].R);
77             que[i].ans=0;
78         }
79         pre_cal();
80         cal();
81     }
82 
83     return 0;
84 }
TLE代码

 

HDU 5381 The sum of gcd (技巧,莫队算法)

标签:

原文地址:http://www.cnblogs.com/xcw0754/p/4734773.html

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