Codeforces 474 F. Ant colony

题目链接:http://codeforces.com/contest/474/problem/F


 

主要就是要求区间$gcd$以及这个区间内的数字等于区间$gcd$的有多少个。

没有修改用个线段树树直支持$gcd$查询,区间不断变大,$gcd$一定单调不增,所以如果左右子树的$gcd$在合并之后保持不变就合并子树的等于$gcd$的数字的数量,不然就可以清空为$0$了。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<cstring>
 8 using namespace std;
 9 #define maxn 1001000
10 #define llg int
11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
12 llg n,m,val[maxn],cs[maxn],T;
13 
14 inline int getint()
15 {
16        int w=0,q=0; char c=getchar();
17        while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); 
18        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w;
19 }
20 
21 struct node
22 {
23     llg val,cs;
24     void init() {val=cs=0;}
25     bool check() {if (val!=0 || cs!=0) return 0; return 1;}
26 };
27 
28 void build(llg o,llg l,llg r)
29 {
30     if (l==r)
31     {
32         val[o]=getint(); cs[o]=1;
33         return ;
34     }
35     llg lc=o<<1,rc=o<<1|1,mid=(l+r)>>1;
36     build(lc,l,mid),build(rc,mid+1,r);
37     //-----------------------Updata
38     val[o]=__gcd(val[lc],val[rc]);
39     if (val[o]==val[lc]) cs[o]+=cs[lc];
40     if (val[o]==val[rc]) cs[o]+=cs[rc];
41 }
42 
43 node ask(llg o,llg l,llg r,llg L,llg R)
44 {
45     if (l>=L && r<=R)
46     {
47         node w;
48         w.cs=cs[o],w.val=val[o];
49         return w;
50     }    
51     node v1,v2;
52     v1.init(),v2.init();
53     llg lc=o<<1,rc=o<<1|1,mid=(l+r)>>1;
54     if (L<=mid)  v1=ask(lc,l,mid,L,R);
55     if (R>mid) v2=ask(rc,mid+1,r,L,R);
56     if (v1.check()) return v2;
57     if (v2.check()) return v1;
58     node vo;
59     vo.init();
60     vo.val=__gcd(v1.val,v2.val);
61     if (vo.val==v1.val) vo.cs+=v1.cs;
62     if (vo.val==v2.val) vo.cs+=v2.cs;
63     return vo;
64 }
65 
66 int main()
67 {
68     yyj("gcd");
69     cin>>n;
70     build(1,1,n);
71     cin>>T;
72     while (T--)
73     {
74         llg l=getint(),r=getint();
75         printf("%d\n",r-l+1-ask(1,1,n,l,r).cs);
76     }
77     return 0;
78 }

 

posted @ 2017-03-31 15:20  №〓→龙光←  阅读(270)  评论(0编辑  收藏  举报