Codeforces914D Bash and a Tough Math Puzzle

题意:一个长度为n的序列,T个询问,2种询问1 l r x问[l, r]区间内替换一个数能不能使得gcd[l, r] == x,输出yes和no,2 l x序列第l个数替换为x

题解:区间询问,单点需修改,线段树,算出区间有t个数不是x的倍数,t>1输出no

#include <bits/stdc++.h>
#define maxn 501000
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int gcd[maxn*4];
void pushup(int x){
    gcd[x] = __gcd(gcd[x<<1], gcd[x<<1|1]);
}
void build(int l,int r,int x){
    if(l == r){
        scanf("%d", &gcd[x]);
        return ;
    }
    int mid = (l+r)>>1;
    build(l, mid, x<<1);
    build(mid+1, r, x<<1|1);
    pushup(x);
}
void update(int l,int r,int x,int t, int c){
    if(l == r){
        gcd[x] = c;
        return ;
    }
    int mid = (l+r)>>1;
    if(t<=mid) update(l, mid, x<<1, t, c);
    else update(mid+1, r, x<<1|1, t, c);
    pushup(x);
}
int query(int l,int r,int x,int L,int R,int g){
    if(l == r){
        return gcd[x]%g?1:0;
    }
    if(L>=l && R<=r&&gcd[x]%g == 0) return 0;
    int mid = l+r>>1;
    if(mid < L) return query(mid+1, r, x<<1|1, L, R, g);
    else if(mid >= R) return query(l, mid, x<<1, L, R, g);
    else{
        int b1 = query(l, mid, x<<1, L, mid, g);
        if(b1 >= 2) return 2;
        int b2 = query(mid+1, r, x<<1|1, mid+1, R, g);
        return b1+b2;
    }
}
int main(){
    int n, t, a, l ,r, x;
    cin>>n;
    build(1, n, 1);
    scanf("%d", &t);
    while(t--){
        scanf("%d", &a);
        if(a == 1){
            scanf("%d%d%d", &l, &r, &x);
            if(query(1, n, 1, l, r, x) <= 1) printf("YES\n");
            else printf("NO\n");
        }
        else {
            scanf("%d%d", &l, &x);
            update(1, n, 1, l, x);
        }
    }
    return 0;
}

 

posted on 2018-01-22 13:18  2855669158  阅读(279)  评论(0)    收藏  举报

导航