Codecraft-18 and Codeforces Round #458 D. Bash and a Tough Math Puzzle ###K
题目链接:https://codeforces.ml/contest/914/problem/D
题意:给定 2个操作, 1是单点修改某个数, 2是问区间中的数能否最多修改一个数的情况下使得区间的gcd=x
思路:考虑线段树维护 每次查询的时候分 左右两个区间,如果查询到的区间长度为1就返回1 因为有一次修改机会,其他的时候在有左右区间的时候
就左区间和右区间看是否gcd都等于x 只有一个区间满足的话就查询另外一个区间 所以每次查询最多就是将一个区间查询到底
cnt 为找到有多少个不是v 的倍数的个数 也就是最多暴力找两个区间 然后剪枝即可 是v的倍数的话不用管 因为此时只需要改一个为v
就能将gcd弄为v 就能够改正回来
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=5e5+10; 4 const int mod=1e9+7; 5 #define ll long long 6 #define ull unsigned long long 7 #define pb push_back 8 #define pi pair<int,ll> 9 #define fi first 10 #define sc second 11 12 13 14 struct ac 15 { 16 int l,r,v; 17 }; 18 ac tr[maxn*4]; 19 int cnt; 20 21 void pushup(int x) 22 { 23 tr[x].v=__gcd(tr[x<<1].v,tr[x<<1|1].v); 24 } 25 26 void build(int x,int l,int r) 27 { 28 tr[x]={l,r,0}; 29 if(l==r) 30 { 31 cin>>tr[x].v; 32 return; 33 } 34 int mid=l+r>>1; 35 build(x<<1,l,mid); 36 build(x<<1|1,mid+1,r); 37 pushup(x); 38 } 39 40 void update(int x,int p,int v) 41 { 42 int L=tr[x].l,R=tr[x].r; 43 if(L==R) 44 { 45 tr[x].v=v; 46 return; 47 } 48 int mid=L+R>>1; 49 if(p<=mid) update(x<<1,p,v); 50 else update(x<<1|1,p,v); 51 pushup(x); 52 } 53 54 void query(int x,int l,int r,int v) 55 { 56 int L=tr[x].l,R=tr[x].r; 57 if(cnt>1) return; 58 if(L==R) 59 { 60 cnt++; 61 return; 62 } 63 int mid=L+R>>1; 64 if(l<=mid&&tr[x<<1].v%v) query(x<<1,l,r,v); 65 if(r>mid&&tr[x<<1|1].v%v) query(x<<1|1,l,r,v); 66 } 67 68 int main() 69 { 70 ios::sync_with_stdio(0); 71 cin.tie(0); 72 int n; 73 cin>>n; 74 build(1,1,n); 75 int q; 76 cin>>q; 77 while(q--) 78 { 79 int t; 80 cin>>t; 81 if(t==1) 82 { 83 int l,r,x; 84 cin>>l>>r>>x; 85 cnt=0; 86 query(1,l,r,x); 87 if(cnt>1) cout<<"NO"<<'\n'; 88 else cout<<"YES"<<'\n'; 89 } 90 else 91 { 92 int i,y; 93 cin>>i>>y; 94 update(1,i,y); 95 } 96 } 97 98 99 100 }
                    
                
                
            
        
浙公网安备 33010602011771号