CodeForces - 914D Bash and a Tough Math Puzzle 数论,线段树
作者:互联网
n <= 5e5
两种操作:
1.询问 L ,R 能否通过修改一个数使得区间gcd为x
2. 修改某点的大小
首先联想到可以用线段树维护区间性质,单点修改。
如果判断1?
如果区间中所有数都是x的倍数,那么只需修改任意一个数变为x就可以。
如果区间中大于一个数不是x的倍数,由于仅仅能修改一次,所以肯定是false
剩下的情况就都可以了
注意线段树细节
struct Tree { int l, r, val , gcd; }; Tree node[maxn * 4]; int a[maxn]; void Pushup(int i) { node[i].gcd = gcd(node[i << 1].gcd, node[i << 1 | 1].gcd); } void Build(int i, int l, int r) { node[i].l = l; node[i].r = r; if (l == r) { node[i].gcd = a[l]; return; } int mid = l + r >> 1; Build(i << 1, l, mid); Build(i << 1 | 1, mid + 1, r); Pushup(i); } void update(int i, int l, int r, int v) { if (node[i].l == node[i].r) { node[i].val = v; node[i].gcd = v; return; } int mid = node[i].l + node[i].r >> 1; if (r <= mid) update(i << 1, l, r, v); else if (l > mid) update(i << 1 | 1, l, r, v); else { update(i << 1, l, mid, v); update(i << 1 | 1, mid + 1, r, v); } Pushup(i); } int query(int rt, int L,int R, int x) { int ans = 0; int mid = node[rt].l + node[rt].r >> 1; if (L <= node[rt].l && R >= node[rt].r && node[rt].gcd % x == 0) return 0; if (node[rt].l == node[rt].r) return 1; if (L <= mid) ans += query(rt << 1, L, R, x); if (ans >= 2) return ans; if (R > mid) ans += query(rt << 1 | 1, L, R, x); return ans; } int main() { int k; int L, R, X; int n = readint(); for (int i = 1; i <= n; i++) a[i] = readint(); Build(1, 1, n); int q = readint(); while (q--) { k = readint(); if (k == 1) { L = readint(), R = readint(); X = readint(); if (query(1, L, R, X) > 1) puts("NO"); else puts("YES"); } else { L = readint(), X = readint(); update(1, L, L, X); } } }
标签:node,rt,Tough,gcd,int,Puzzle,CodeForces,修改,return 来源: https://www.cnblogs.com/hznumqf/p/13450730.html