codeforces #271(div2) F. Ant colony

题意:一个数列,q个询问,问某个区间,如果某个数是其他数的因子,则s++,问r-l+1-s是多少

思路:一个数是其他数的因子,这个数肯定是最小数,且为这个区间的gcd,所以RMQ求区间GCD,区间最小值,在用线段树求这个区间最小值个数

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 const int N=1e5+10;
  5 
  6 ll dp1[N][20],dp2[N][20],a[N];
  7 int n;
  8 
  9 void init(){
 10     memset(dp2,127,sizeof(dp2));
 11     for(int i=1;i<=n;i++)
 12         dp1[i][0]=dp2[i][0]=a[i];
 13     for(int j=1;(1<<j)<=n;j++){
 14         for(int i=1;i+(1<<j)-1<=n;i++)
 15         {
 16             dp1[i][j]=__gcd(dp1[i][j-1],dp1[i+(1<<(j-1))][j-1]);
 17             dp2[i][j]=min(dp2[i][j-1],dp2[i+(1<<(j-1))][j-1]);
 18         }
 19     }
 20 }
 21 int  check(int x,int y){
 22     int kk=0;
 23     while((1<<(kk+1))<=y-x+1) kk++;
 24     int Min=min(dp2[x][kk],dp2[y-(1<<kk)+1][kk]);
 25     return Min;
 26 }
 27 int  check1(int x,int y){
 28     int kk=0;
 29     while((1<<(kk+1))<=y-x+1) kk++;
 30     int Min=__gcd(dp1[x][kk],dp1[y-(1<<kk)+1][kk]);
 31     return Min;
 32 }
 33 struct node{
 34     int l,r,M,num;
 35 }e[N*4];
 36 
 37 void build(int x,int L,int R){
 38     e[x].l=L;e[x].r=R;
 39 
 40     if(L==R){
 41         e[x].M=a[L];e[x].num=1;return ;
 42     }
 43     int mid=(L+R)>>1;
 44     build(2*x,L,mid);
 45     build(2*x+1,mid+1,R);
 46     if(e[2*x].M==e[2*x+1].M){
 47         e[x].M=e[2*x].M;
 48         e[x].num=e[x*2].num+e[2*x+1].num;
 49     }
 50     else {
 51         if(e[2*x].M<e[2*x+1].M){
 52             e[x].M=e[2*x].M;e[x].num=e[2*x].num;
 53         }
 54         else
 55         {
 56              e[x].M=e[2*x+1].M;e[x].num=e[2*x+1].num;
 57         }
 58     }
 59 }
 60 
 61 int sum;
 62 void  query(int x,int L,int R,int y){
 63     if(e[x].l>=L&&R>=e[x].r){
 64         if(e[x].M==y) {
 65             sum+=e[x].num;
 66         }
 67         return ;
 68     }
 69     int mid=(e[x].l+e[x].r)>>1;
 70     if(mid>=R)  query(2*x,L,R,y);
 71     else if(L>mid) query(2*x+1,L,R,y);
 72     else {
 73         query(2*x,L,mid,y);
 74         query(2*x+1,mid+1,R,y);
 75     }
 76 }
 77 int main(){
 78     scanf("%d",&n);
 79     for(int i=1;i<=n;i++){
 80         scanf("%d",&a[i]);
 81     }
 82     build(1,1,n);
 83     init();
 84     int q;
 85 
 86     cin>>q;
 87     int x,y;
 88     while(q--){
 89         scanf("%d%d",&x,&y);
 90         ll z=check(x,y);
 91         ll zz=check1(x,y);
 92        // cout<<z<<" "<<zz<<endl;
 93         if(z==zz){
 94             sum=0;
 95             query(1,x,y,zz);
 96             printf("%d\n",y-x+1-sum);
 97         }
 98         else {
 99             printf("%d\n",y-x+1);
100         }
101     }
102 }

 

posted on 2017-07-30 19:57  hhhhx  阅读(120)  评论(0编辑  收藏  举报

导航