【Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined) D】Bash and a Tough Math Puzzle
2018-01-22 16:28
495 查看
【链接】 我是链接,点我呀:)
【题意】
在这里输入题意
【题解】
对于1操作
令len = r-l+1
等价于查找l..r这个范围内x的倍数的个数是否大于等于len-1
也即l..r这个范围内不是x的倍数的个数小于等于1个
(因为如果改的话,肯定是把那个数字改成x,其他n-1个数必须是x的倍数,只有这样gcd才会为x
(不用改的情况则不一定里面就一定有x,但肯定都是x的倍数
(所以我们改的时候,实际上是一个贪心的过程,就强行把那个不是x的倍数的数改成x
(或者是虽然都是x的倍数,但gcd比x大,那么就任意把一个数字改成x就好了,gcd肯定就变成x了
(这样加上"其他n-1个数字都是x的倍数"这个限制,整体的gcd就是x了
这个可以通过建立线段树来实现。
因为gcd有交换律。
所以合并的时候,只要把左边的gcd和右边的gcd一起求一个gcd就行了。
这样。我们在某个区间内。
设l..mid的gcd为xx
设mid+1..r的gcd为yy
如果gcd(xx,x)!=x 且 gcd(yy,x)!=x
也就是说左右两个子区间的gcd都不是x的倍数。
那么就直接返回无解。
(因为这就表示这两个区间分别有一个数字不是x的倍数,即不是x的倍数的个数>1,所以无解
如果gcd(xx,x)==x且gcd(yy,x)==x
就说明左右两个区间的gcd都是x的倍数。
那么这两个区间里面的数字肯定都是x的倍数。
也可以直接返回。
否则如果gcd(xx,x)!=x那么就往左区间继续递归。
如果gcd(yy,x)!=x那么就往右区间继续递归。
中间如果发现不是x的倍数的个数超过了1就直接退出
2操作就是线段树的单点更新。
【代码】
#include<bits/stdc++.h> using namespace std; #define ll long long #define rson m+1,r,rt<<1|1 #define lson l,m,rt<<1 using namespace std; const int N=5e5+7; int n,i,j,a ,tr[N<<2],now,x; void build(int l=1,int r=n,int rt=1) { if(l==r){ tr[rt]=a[l]; return; } int m=(l+r)>>1; build(lson); build(rson); tr[rt]=__gcd( tr[rt<<1] , tr[rt<<1|1]); } void query(int L,int R,int l=1,int r=n,int rt=1) { if (now>1) return; int m=(l+r)>>1; if(L<=l&&r<=R) { if (l==r){ if (__gcd(tr[rt],x)!=x) now++; return; } int xx = __gcd(tr[rt<<1],x),yy = __gcd(tr[rt<<1|1],x); if (xx!=x && yy!=x){ now+=2; return; }else if (xx==x && yy==x) return; if (xx!=x) query(L,R,lson); if (yy!=x) query(L,R,rson); return; } if (L<=m) query(L,R,lson); if (m<R) query(L,R,rson); } void updata(int p,int num,int l = 1,int r = n,int rt = 1){ if (l==r){ a[l] = num; tr[rt] = a[l]; return; } int m = (l+r)>>1; if (p<=m) updata(p,num,lson); else updata(p,num,rson); tr[rt]=__gcd( tr[rt<<1] , tr[rt<<1|1]); } int main() { #ifdef LOCAL_DEFINE freopen("rush_in.txt", "r", stdin); #endif ios::sync_with_stdio(0),cin.tie(0); cin >>n; for (int i = 1;i <= n;i++) cin >>a[i]; build(); int Q; cin >> Q; while (Q--){ int ope; cin >>ope; if (ope==2){ int i,y; cin >> i >> y; updata(i,y); }else{ int l,r; cin >> l >> r >> x; now = 0; query(l,r); if (now>1){ cout<<"NO"<<endl; }else{ cout <<"YES"<<endl; } } } return 0; }
相关文章推荐
- Codecraft-18 and Codeforces Round #458: D. Bash and a Tough Math Puzzle(线段树)
- Codecraft-18 and Codeforces Round #458 D. Bash and a Tough Math Puzzle(线段树)
- Codecraft-18 and Codeforces Round #458 (D)-Bash and a Tough Math Puzzle(线段树)
- Codeforces Round #458 D. Bash and a Tough Math Puzzle(线段树)
- CodeCraft-18 and Codeforces Round #458(Div. 1+Div. 2,combined)
- Bash and a Tough Math Puzzle
- Codeforces 914D - Bash and a Tough Math Puzzle 【线段树】
- Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined) -- B. Bash's Big Day (唯一分解定理)
- Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined)C,D详解
- Codeforces Round#458Div.1+2 D.Bash and a Tough Math Puzzle 区间GCD
- Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined)
- CF 914 D. Bash and a Tough Math Puzzle
- codeforce 914-D. Bash and a Tough Math Puzzle(线段树)
- Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined) B - Bash's Big Day 枚举
- codeforces 914 D Bash and a Tough Math Puzzle
- Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined) B题(博弈)
- Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined) E. Palindromes in a Tree(点分治)
- 【Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined) A】 Perfect Squares
- 【Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined) B】 Conan and Agasa play a Card Game
- 【Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined) C】 Travelling Salesman and Special Numbers