codeforces 914 D Bash and a Tough Math Puzzle

Posted xu-daxia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
");
67             else printf("NO
");
68         }
69         else{
70             int x,y;
71             scanf("%d%d",&x,&y);
72             change(x,y,1);
73         }
74     }
75     return 0;
76 }
View Code

 

题意

?给出一段序列(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的倍数,一个不是,那就递归处理不是的那个区间。

 

以上是关于codeforces 914 D Bash and a Tough Math Puzzle的主要内容,如果未能解决你的问题,请参考以下文章

CF 914 D. Bash and a Tough Math Puzzle

Codeforces 914D - Bash and a Tough Math Puzzle 线段树,区间GCD

Codeforces 914 C Travelling Salesman and Special Numbers

914D Bash and a Tough Math Puzzle

Codecraft-18 and Codeforces Round #458:D,Bash and a Tough Math Puzzle

[CF914D]Bash and a Tough Math Puzzle