codeforces 914 D Bash and a Tough Math Puzzle
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cstdio> 6 using namespace std; 7 const int N=500100; 8 int n,a[N],m; 9 struct tree{ 10 int l,r,gcd; 11 }tr[N*5]; 12 int gcd(int x,int y){ 13 if(y==0)return x; 14 else return gcd(y,x%y); 15 } 16 void build(int l,int r,int now){ 17 tr[now].l=l;tr[now].r=r; 18 if(l==r){ 19 tr[now].gcd=a[l]; 20 return; 21 } 22 int mid=(l+r)>>1; 23 build(l,mid,now*2); 24 build(mid+1,r,now*2+1); 25 tr[now].gcd=gcd(tr[now*2].gcd,tr[now*2+1].gcd); 26 } 27 void change(int x,int y,int now){ 28 // cout<<tr[now].l<<" "<<tr[now].r<<" "<<x<<endl; 29 if(tr[now].l==x&&tr[now].r==x){ 30 tr[now].gcd=y; 31 return ; 32 } 33 int mid=(tr[now].l+tr[now].r)>>1; 34 if(x>mid)change(x,y,now*2+1); 35 else change(x,y,now*2); 36 tr[now].gcd=gcd(tr[now*2].gcd,tr[now*2+1].gcd); 37 } 38 int check(int l,int r,int x,int now){ 39 if(tr[now].gcd%x==0)return 0; 40 if(tr[now].l==l&&tr[now].r==r){ 41 if(l==r)return 1; 42 if(tr[now*2].gcd%x==0)return check(tr[now*2+1].l,tr[now*2+1].r,x,now*2+1); 43 if(tr[now*2+1].gcd%x==0)return check(tr[now*2].l,tr[now*2].r,x,now*2); 44 return 2; 45 } 46 int mid=(tr[now].l+tr[now].r)>>1; 47 if(l>mid)return check(l,r,x,now*2+1); 48 else if(r<=mid)return check(l,r,x,now*2); 49 else{ 50 return check(l,mid,x,now*2)+check(mid+1,r,x,now*2+1); 51 } 52 } 53 int main(){ 54 scanf("%d",&n); 55 for(int i=1;i<=n;i++){ 56 scanf("%d",&a[i]); 57 } 58 build(1,n,1); 59 scanf("%d",&m); 60 for(int i=1;i<=m;i++){ 61 int k; 62 scanf("%d",&k); 63 if(k==1){ 64 int l,r,x; 65 scanf("%d%d%d",&l,&r,&x); 66 if(check(l,r,x,1)<=1)printf("YES\n"); 67 else printf("NO\n"); 68 } 69 else{ 70 int x,y; 71 scanf("%d%d",&x,&y); 72 change(x,y,1); 73 } 74 } 75 return 0; 76 }
题意
•给出一段序列(1≤n≤5*105),两个操作(1≤q≤4*105)
•操作1 给出l,r,x
•求区间l-r的gcd,如果至多能改掉区间内的一个数,使gcd是x的倍数,那么输出YES,否则输出NO
•操作2 给出pos,x
•将序列中pos位置上的数字改为x
题解
线段树,维护区间的gcd
因为题目询问删除一个数,我们把整个区间分成两块,如果两边的gcd都是x的倍数显然是可以的,如果都不是gcd的倍数,就不行了,因为使两个gcd的gcd为x的倍数,这两个gcd应该都至少含有x因子。如果一个gcd是x的倍数,一个不是,那就递归处理不是的那个区间。