1. 程式人生 > 其它 >區間最大公約數(線段樹模板)

區間最大公約數(線段樹模板)

連結

  1 #include <bits/stdc++.h>
  2 #define go continue
  3 #define int long long
  4 #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  5 #define fory(i,a,b) for(int i = a; i <= b; ++i)
  6 using namespace std;
  7 
  8 template <typename T> inline void read(T& t) {
9 int f = 0, c = getchar(); 10 t = 0; 11 while (!isdigit(c)) f |= c == '-', c = getchar(); 12 while (isdigit(c)) t = t * 10 + c - 48, c = getchar(); 13 if (f) t = -t; 14 } 15 16 template <typename T> void print(T x) { 17 if (x < 0) x = -x, putchar('-'); 18 if
(x > 9) print(x / 10); 19 putchar(x % 10 + 48); 20 } 21 22 const int N = 5e5 + 10; 23 24 int n, m, a[N]; 25 26 inline int gcd(int a, int b) { 27 return b ? gcd(b, a % b) : a; 28 } 29 30 struct node { 31 int l, r, sum, d; 32 }; 33 34 struct segment_tree { 35 36 node t[N << 2
]; 37 int mp[N]; 38 39 inline void help_push(node& a, node& b, node& c) { 40 a.sum = b.sum + c.sum; 41 a.d = gcd(b.d, c.d); 42 } 43 44 inline void push_up(int root) { 45 int ch = root << 1; 46 help_push(t[root], t[ch], t[ch + 1]); 47 } 48 49 inline void build(int root, int l, int r) { 50 t[root].l = l; 51 t[root].r = r; 52 if(l != r) { 53 int ch = root << 1; 54 int mid = (l + r) >> 1; 55 build(ch, l, mid); 56 build(ch + 1, mid + 1, r); 57 push_up(root); 58 } else { 59 int tmp = a[l] - a[l - 1]; 60 t[root].d = tmp; 61 t[root].sum = tmp; 62 mp[l] = root; 63 } 64 } 65 66 inline void change(int root, int x, int y) { 67 x = mp[x]; 68 t[x].d = t[x].sum + y; 69 t[x].sum += y; 70 71 while(x >>= 1) push_up(x); 72 } 73 74 inline node query(int root, int l, int r) { 75 if(t[root].l >= l && t[root].r <= r) { 76 return t[root]; 77 } else { 78 int ch = root << 1; 79 int mid = (t[root].l + t[root].r) >> 1; 80 81 if(mid >= r) return query(ch, l, r); 82 else if(l > mid) return query(ch + 1, l, r); 83 else { 84 node left = query(ch, l, mid); 85 node right = query(ch + 1, mid + 1, r); 86 node res; 87 help_push(res, left, right); 88 return res; 89 } 90 } 91 } 92 93 } st; 94 95 int l, r, x; 96 char op[2]; 97 98 signed main() { 99 read(n), read(m); 100 fory(i, 1, n) read(a[i]); 101 102 st.build(1, 1, n); 103 104 while(m--) { 105 scanf("%s%lld%lld", op, &l, &r); 106 if(*op == 'C') { 107 read(x); 108 st.change(1, l, x); 109 if(r + 1 <= n) st.change(1, r + 1, -x); 110 } else { 111 node ll = st.query(1, 1, l); 112 node rr = {0, 0, 0, 0}; 113 if(l + 1 <= r) rr = st.query(1, l + 1, r); 114 printf("%lld\n", abs(gcd(ll.sum, rr.d))); 115 } 116 } 117 return 0; 118 } 119 /* 120 input: 121 5 5 122 1 3 5 7 9 123 Q 1 5 124 C 1 5 1 125 Q 1 5 126 C 3 3 6 127 Q 2 4 128 output: 129 1 130 2 131 4 132 133 ps: 134 C l r d 修改操作 [l, r] + d 135 Q l r 詢問操作 [l, r] 的區間GCD 136 */