CodeForces 474F 线段树水题:求区间gcd和区间最小值,最小值个数

 1 #include<stdio.h>
 2 #include<string.h>
 3 int a[1000005],minv[1000005],num[1000005],gcdv[1000005];
 4 int gcd(int x,int y)
 5 {
 6     if (y==0) return x;
 7     return gcd(y,x%y);
 8 }
 9 void build(int o,int l,int r)
10 {
11     if (l==r) {gcdv[o]=a[l]; minv[o]=a[l]; num[o]=1; return; }
12     int mid=(l+r)/2;
13     build(o*2,l,mid); build(o*2+1,mid+1,r);
14     gcdv[o]=gcd(gcdv[o*2],gcdv[o*2+1]);
15     if (minv[o*2]==minv[o*2+1]) { num[o]=num[o*2]+num[o*2+1]; minv[o]=minv[o*2]; }
16     else if (minv[o*2]<minv[o*2+1]){ num[o]=num[o*2]; minv[o]=minv[o*2]; }
17     else{ num[o]=num[o*2+1]; minv[o]=minv[o*2+1]; }
18 }
19 int query1(int o,int l,int r,int y1,int y2)
20 {
21     if (y1<=l&&y2>=r) return gcdv[o];
22     int t1=0,t2=0,mid=(l+r)/2;
23     if (y1<=mid) t1=query1(o*2,l,mid,y1,y2);
24     if (y2>mid) t2=query1(o*2+1,mid+1,r,y1,y2);
25     if (t1==0) return t2;
26     if (t2==0) return t1;
27     return gcd(t1,t2);
28 }
29 int query2(int o,int l,int r,int y1,int y2)
30 {
31     if (y1<=l&&y2>=r) return minv[o];
32     int t1=0x3f3f3f3f,t2=0x3f3f3f3f,mid=(l+r)/2;
33     if (y1<=mid) t1=query2(o*2,l,mid,y1,y2);
34     if (y2>mid) t2=query2(o*2+1,mid+1,r,y1,y2);
35     if (t1<t2) return t1; return t2;
36 }
37 int query3(int o,int l,int r,int y1,int y2)
38 {
39     if (y1<=l&&y2>=r) return num[o];
40     int t1=0x3f3f3f3f,t2=0x3f3f3f3f,t3,t4,mid=(l+r)/2;
41     if (y1<=mid) { t1=query2(o*2,l,mid,y1,y2); t3=query3(o*2,l,mid,y1,y2); }
42     if (y2>mid) {t2=query2(o*2+1,mid+1,r,y1,y2); t4=query3(o*2+1,mid+1,r,y1,y2); }
43     if (t1==t2) return t3+t4;
44     else if (t1<t2) return t3;
45     else return t4;
46 }
47 int main()
48 {
49     int n,i,m,p,q,x1,x2,cnt;
50     scanf("%d",&n);
51     for (i=1;i<=n;i++) scanf("%d",&a[i]);
52     build(1,1,n);
53     scanf("%d",&m);
54     while (m--)
55     {
56         scanf("%d%d",&p,&q);
57         x1=query1(1,1,n,p,q);
58         cnt=query3(1,1,n,p,q);
59         x2=query2(1,1,n,p,q);
60    //   printf("ww %d %d %d\n",x1,x2,cnt);
61         if (x1==x2) printf("%d\n",q-p+1-cnt);
62         else printf("%d\n",q-p+1);
63     }
64 }

http://codeforces.com/contest/474/problem/F

posted on 2014-10-07 18:44  xiao_xin  阅读(293)  评论(0编辑  收藏  举报

导航