1. 程式人生 > 其它 >資料結構模板

資料結構模板

P2023 [AHOI2009] 維護序列

動態開點線段樹,區間加,區間乘,區間求和。

  1 #include <iostream>
  2 #include <cstdio>
  3 using namespace std;
  4 typedef long long ll;
  5 typedef unsigned long long ull;
  6 typedef long double ld;
  7 #define space putchar(' ')
  8 #define enter putchar('\n')
  9 #define debug(x) cerr << #x << " = " << x << endl
 10
11 namespace Fast 12 { 13 template<typename T> inline void read(T &s) 14 { 15 s = 0; bool f = false; char c = getchar(); 16 while (c < '0' || c > '9') { if (c == '-') f = true; c = getchar(); } 17 while (c >= '0' && c <= '9') s = (s << 3
) + (s << 1) + (c ^ 48), c = getchar(); 18 if (f) s = ~s + 1; 19 } 20 template<typename T> inline T Abs(T x) { return x > 0 ? x : -x; } 21 template<typename T> inline T Max(T x, T y) { return x > y ? x : y; } 22 template<typename T> inline T Min(T x, T y) { return
x < y ? x : y; } 23 template<typename T> inline void addmod(T &x, T p) { if (x >= p) x -= p; } 24 template<typename T> inline void submod(T &x, T p) { if (x < 0) x += p; } 25 template<typename T, typename ...Args> inline void read(T& x, Args&... others) 26 { 27 read(x), read(others...); 28 } 29 template<typename T, typename ...Args> inline T Max(T x, T y, Args... others) 30 { 31 return Max(Max(x, y), others...); 32 } 33 template<typename T, typename ...Args> inline T Min(T x, T y, Args... others) 34 { 35 return Min(Min(x, y), others...); 36 } 37 } 38 using namespace Fast; 39 40 const int N = 1e5 + 10; 41 int n, root, cnt; ll p, a[N]; 42 struct node 43 { 44 int ls, rs, l, r; ll addtag, multag, sum; 45 node() { clear(); } 46 inline void clear() { ls = rs = l = r = addtag = sum = 0, multag = 1; } 47 } t[N << 2]; 48 49 inline void pushup(int x) { addmod(t[x].sum = t[t[x].ls].sum + t[t[x].rs].sum, p); } 50 inline void pushdown(int x) 51 { 52 t[t[x].ls].sum = (t[t[x].ls].sum * t[x].multag + t[x].addtag * (t[t[x].ls].r - t[t[x].ls].l + 1)) % p; 53 t[t[x].ls].addtag = (t[t[x].ls].addtag * t[x].multag + t[x].addtag) % p; 54 t[t[x].ls].multag = t[t[x].ls].multag * t[x].multag % p; 55 t[t[x].rs].sum = (t[t[x].rs].sum * t[x].multag + t[x].addtag * (t[t[x].rs].r - t[t[x].rs].l + 1)) % p; 56 t[t[x].rs].addtag = (t[t[x].rs].addtag * t[x].multag + t[x].addtag) % p; 57 t[t[x].rs].multag = t[t[x].rs].multag * t[x].multag % p; 58 t[x].addtag = 0, t[x].multag = 1; 59 } 60 inline void build(int &x, int l, int r) 61 { 62 if (!x) x = ++cnt; t[x].l = l, t[x].r = r; 63 if (l == r) { t[x].sum = a[l]; return; } 64 int mid = l + r >> 1; 65 build(t[x].ls, l, mid); 66 build(t[x].rs, mid + 1, r); 67 pushup(x); 68 } 69 inline void addmodify(int x, int l, int r, ll v) 70 { 71 if (l <= t[x].l && t[x].r <= r) 72 { 73 t[x].sum = (t[x].sum + v * (t[x].r - t[x].l + 1)) % p; 74 addmod(t[x].addtag += v, p); 75 return; 76 } 77 pushdown(x); int mid = t[x].l + t[x].r >> 1; 78 if (l <= mid) addmodify(t[x].ls, l, r, v); 79 if (mid < r) addmodify(t[x].rs, l, r, v); 80 pushup(x); 81 } 82 inline void mulmodify(int x, int l, int r, ll v) 83 { 84 if (l <= t[x].l && t[x].r <= r) 85 { 86 t[x].sum = t[x].sum * v % p; 87 t[x].addtag = t[x].addtag * v % p; 88 t[x].multag = t[x].multag * v % p; 89 return; 90 } 91 pushdown(x); int mid = t[x].l + t[x].r >> 1; 92 if (l <= mid) mulmodify(t[x].ls, l, r, v); 93 if (mid < r) mulmodify(t[x].rs, l, r, v); 94 pushup(x); 95 } 96 inline ll query(int x, int l, int r) 97 { 98 if (l <= t[x].l && t[x].r <= r) return t[x].sum; 99 pushdown(x); int mid = t[x].l + t[x].r >> 1; ll ans = 0; 100 if (l <= mid) ans += query(t[x].ls, l, r); 101 if (mid < r) ans += query(t[x].rs, l, r); 102 addmod(ans, p); return ans; 103 } 104 105 int main() 106 { 107 int m, opt, l, r, v; 108 read(n, p); root = ++cnt; 109 for (int i = 1; i <= n; i++) read(a[i]); 110 build(root, 1, n); read(m); 111 while (m--) 112 { 113 read(opt, l, r); if (opt <= 2) read(v); 114 if (opt == 1) mulmodify(root, l, r, v); 115 else if (opt == 2) addmodify(root, l, r, v); 116 else cout << query(root, l, r), enter; 117 } 118 return 0; 119 }
AC Code