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 }
View Code

 

posted @ 2020-10-15 23:00  canwinfor  阅读(74)  评论(0)    收藏  举报