[题目链接]
https://codeforces.com/contest/914/problem/D
[算法]
显然 , 当一个区间[l , r]中为d倍数的数的个数 <= 1 , 答案为Yes , 否则为No
线段树简单维护即可 , 详见代码 , 时间复杂度 : O(NlogN ^ 2)
[代码]
#include<bits/stdc++.h> using namespace std; const int MAXN = 5e5 + 10; int n , m; int val[MAXN]; int cnt; struct Segment_Tree { struct Node { int l , r; int value; } a[MAXN << 2]; inline int gcd(int x , int y) { if (y == 0) return x; else return gcd(y , x % y); } inline void update(int x) { a[x].value = gcd(a[x << 1].value , a[x << 1 | 1].value); } inline void build(int index , int l , int r) { a[index].l = l , a[index].r = r; if (l == r) { a[index].value = val[l]; return; } int mid = (l + r) >> 1; build(index << 1 , l , mid); build(index << 1 | 1 , mid + 1 , r); update(index); } inline void modify(int index , int x , int y) { if (a[index].l == a[index].r) { a[index].value = y; return; } else { int mid = (a[index].l + a[index].r) >> 1; if (mid >= x) modify(index << 1 , x , y); else modify(index << 1 | 1 , x , y); update(index); } } inline void getans(int index , int l , int r , int d) { if (cnt > 1) return; int mid = (a[index].l + a[index].r) >> 1; if (a[index].l == l && a[index].r == r) { if (l == r) { if (a[index].value % d) ++cnt; return; } if ((a[index << 1].value % d) && (a[index << 1 | 1].value % d)) { cnt += 2; return; } else if (a[index << 1].value % d) getans(index << 1 , l , mid , d); else if (a[index << 1 | 1].value % d) getans(index << 1 | 1 , mid + 1 , r , d); } else { if (mid >= r) getans(index << 1 , l , r , d); else if (mid + 1 <= l) getans(index << 1 | 1 , l , r , d); else { getans(index << 1 , l , mid , d); getans(index << 1 | 1 , mid + 1 , r , d); } } } } SGT; template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); } template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } int main() { read(n); for (int i = 1; i <= n; i++) read(val[i]); SGT.build(1 , 1 , n); read(m); while (m--) { int type; read(type); if (type == 1) { int l , r , x; read(l); read(r); read(x); cnt = 0; SGT.getans(1 , l , r , x); if (cnt > 1) printf("NO "); else printf("YES "); } else { int x , y; read(x); read(y); SGT.modify(1 , x , y); } } return 0; }