1. 程式人生 > >[Codeforces 914D] Bash and a Tough Math Puzzle

[Codeforces 914D] Bash and a Tough Math Puzzle

[題目連結]

         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\n"); else printf("YES\n"); } else { int x , y; read(x); read(y); SGT.modify(1 , x , y); } } return 0; }