fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #ifdef LOCAL
  5. #define DEBUG(...) debug(#__VA_ARGS__, __VA_ARGS__)
  6. #else
  7. #define DEBUG(...) 6
  8. #endif
  9.  
  10. template<typename T, typename S> ostream& operator << (ostream &os, const pair<T, S> &p) {return os << "(" << p.first << ", " << p.second << ")";}
  11. template<typename C, typename T = decay<decltype(*begin(declval<C>()))>, typename enable_if<!is_same<C, string>::value>::type* = nullptr>
  12. ostream& operator << (ostream &os, const C &c) {bool f = true; os << "["; for (const auto &x : c) {if (!f) os << ", "; f = false; os << x;} return os << "]";}
  13. template<typename T> void debug(string s, T x) {cerr << "\033[1;35m" << s << "\033[0;32m = \033[33m" << x << "\033[0m\n";}
  14. template<typename T, typename... Args> void debug(string s, T x, Args... args) {for (int i=0, b=0; i<(int)s.size(); i++) if (s[i] == '(' || s[i] == '{') b++; else
  15. if (s[i] == ')' || s[i] == '}') b--; else if (s[i] == ',' && b == 0) {cerr << "\033[1;35m" << s.substr(0, i) << "\033[0;32m = \033[33m" << x << "\033[31m | "; debug(s.substr(s.find_first_not_of(' ', i + 1)), args...); break;}}
  16.  
  17. template<int MOD>
  18. struct ModInt {
  19. long long v;
  20. ModInt(long long _v = 0) {v = (-MOD < _v && _v < MOD) ? _v : _v % MOD; if (v < 0) v += MOD;}
  21. ModInt& operator += (const ModInt &other) {v += other.v; if (v >= MOD) v -= MOD; return *this;}
  22. ModInt& operator -= (const ModInt &other) {v -= other.v; if (v < 0) v += MOD; return *this;}
  23. ModInt& operator *= (const ModInt &other) {v = v * other.v % MOD; return *this;}
  24. ModInt& operator /= (const ModInt &other) {return *this *= inverse(other);}
  25. bool operator == (const ModInt &other) const {return v == other.v;}
  26. bool operator != (const ModInt &other) const {return v != other.v;}
  27. friend ModInt operator + (ModInt a, const ModInt &b) {return a += b;}
  28. friend ModInt operator - (ModInt a, const ModInt &b) {return a -= b;}
  29. friend ModInt operator * (ModInt a, const ModInt &b) {return a *= b;}
  30. friend ModInt operator / (ModInt a, const ModInt &b) {return a /= b;}
  31. friend ModInt operator - (const ModInt &a) {return 0 - a;}
  32. friend ModInt power(ModInt a, long long b) {ModInt ret(1); while (b > 0) {if (b & 1) ret *= a; a *= a; b >>= 1;} return ret;}
  33. friend ModInt inverse(ModInt a) {return power(a, MOD - 2);}
  34. friend istream& operator >> (istream &is, ModInt &m) {is >> m.v; m.v = (-MOD < m.v && m.v < MOD) ? m.v : m.v % MOD; if (m.v < 0) m.v += MOD; return is;}
  35. friend ostream& operator << (ostream &os, const ModInt &m) {return os << m.v;}
  36. };
  37. using M = ModInt<1000000007>;
  38.  
  39. struct SegmentTree {
  40. struct Node {
  41. int ti, lazyTi, l, r;
  42. bool flag;
  43. M sum, sumsq, ans, lazy, cumsum, cumsumsq;
  44.  
  45. void leaf(int val) {
  46. ti = lazyTi = 0;
  47. flag = false;
  48. sum = val;
  49. sumsq = M(val) * val;
  50. ans = lazy = cumsum = cumsumsq = 0;
  51. }
  52.  
  53. void pull(const Node &a, const Node &b) {
  54. sum = a.sum + b.sum;
  55. sumsq = a.sumsq + b.sumsq;
  56. ti = max(a.ti, b.ti);
  57. ans = a.ans + b.ans + (ti - a.ti) * a.sumsq + (ti - b.ti) * b.sumsq;
  58. }
  59.  
  60. void push(const Node &other) {
  61. if (flag) {
  62. cumsumsq += lazy * lazy * (other.lazyTi - lazyTi) + 2 * lazy * other.cumsum + other.cumsumsq;
  63. cumsum += lazy * (other.lazyTi - lazyTi) + other.cumsum;
  64. } else {
  65. cumsumsq = other.cumsumsq;
  66. cumsum = other.cumsum;
  67. }
  68. lazy += other.lazy;
  69. lazyTi = other.lazyTi;
  70. flag = true;
  71. }
  72.  
  73. void apply() {
  74. // a^2 part
  75. ans += sumsq * (lazyTi - ti);
  76. // 2a * sum part
  77. ans += 2 * sum * cumsum;
  78. // sum^2 part
  79. ans += (r - l + 1) * cumsumsq;
  80. // update rest of stuff
  81. sumsq += 2 * sum * lazy + (r - l + 1) * lazy * lazy;
  82. sum += (r - l + 1) * lazy;
  83. ti = lazyTi;
  84. flag = false;
  85. lazy = cumsum = cumsumsq = 0;
  86. }
  87. };
  88.  
  89. int n;
  90. vector<int> a;
  91. vector<Node> st;
  92.  
  93. SegmentTree(int _n) : n(_n), a(n), st(4*n) {
  94. build(1, 0, n-1);
  95. }
  96.  
  97. SegmentTree(const vector<int> &_a) : n((int) _a.size()), a(_a), st(4*n) {
  98. build(1, 0, n-1);
  99. }
  100.  
  101. void build(int p, int l, int r) {
  102. st[p].l = l;
  103. st[p].r = r;
  104. if (l == r) {
  105. st[p].leaf(a[l]);
  106. return;
  107. }
  108. int m = (l + r) / 2;
  109. build(2*p, l, m);
  110. build(2*p+1, m+1, r);
  111. st[p].pull(st[2*p], st[2*p+1]);
  112. }
  113.  
  114. void push(int p) {
  115. if (st[p].flag) {
  116. if (st[p].l != st[p].r) {
  117. st[2*p].push(st[p]);
  118. st[2*p+1].push(st[p]);
  119. }
  120. st[p].apply();
  121. }
  122. }
  123.  
  124. Node query(int p, int i, int j) {
  125. push(p);
  126. if (st[p].l == i && st[p].r == j)
  127. return st[p];
  128. int m = (st[p].l + st[p].r) / 2;
  129. if (j <= m)
  130. return query(2*p, i, j);
  131. else if (i > m)
  132. return query(2*p+1, i, j);
  133. Node ret, ls = query(2*p, i, m), rs = query(2*p+1, m+1, j);
  134. ret.pull(ls, rs);
  135. return ret;
  136. }
  137.  
  138. M query(int i, int j, long long ti) {
  139. Node ret = query(1, i, j);
  140. return ret.ans + (ti - ret.ti) * ret.sumsq;
  141. }
  142.  
  143. void update(int p, int i, int j, int val, int ti) {
  144. if (st[p].l == i && st[p].r == j) {
  145. Node cur;
  146. cur.flag = true;
  147. cur.lazyTi = ti;
  148. cur.lazy = val;
  149. cur.cumsum = cur.cumsumsq = 0;
  150. st[p].push(cur);
  151. push(p);
  152. return;
  153. }
  154. push(p);
  155. int m = (st[p].l + st[p].r) / 2;
  156. if (j <= m) {
  157. update(2*p, i, j, val, ti);
  158. push(2*p+1);
  159. } else if (i > m) {
  160. push(2*p);
  161. update(2*p+1, i, j, val, ti);
  162. } else {
  163. update(2*p, i, m, val, ti);
  164. update(2*p+1, m+1, j, val, ti);
  165. }
  166. st[p].pull(st[2*p], st[2*p+1]);
  167. }
  168.  
  169. void update(int i, int j, int val, int ti) {
  170. update(1, i, j, val, ti);
  171. }
  172. };
  173.  
  174. int main() {
  175. ios_base::sync_with_stdio(false);
  176. cin.tie(NULL);
  177.  
  178. int n, m, q;
  179. cin >> n >> m >> q;
  180. vector<int> a(n);
  181. for (int i=0; i<n; i++)
  182. cin >> a[i];
  183.  
  184. vector<array<int, 3>> modif;
  185. for (int i=0; i<m; i++) {
  186. int l, r, x;
  187. cin >> l >> r >> x;
  188. l--, r--;
  189. modif.push_back({l, r, x});
  190. }
  191.  
  192. vector<vector<array<int, 4>>> queries(m + 1);
  193. for (int i=0; i<q; i++) {
  194. int l, r, x, y;
  195. cin >> l >> r >> x >> y;
  196. l--, r--;
  197. if (x > 0)
  198. queries[x-1].push_back({l, r, i, -1});
  199. queries[y].push_back({l, r, i, 1});
  200. }
  201.  
  202. SegmentTree st(a);
  203. vector<M> ret(q);
  204. for (int i=0; i<m; i++) {
  205. for (auto [l, r, j, c] : queries[i])
  206. ret[j] += c * st.query(l, r, (long long) i + 1);
  207. st.update(modif[i][0], modif[i][1], modif[i][2], i + 1);
  208. }
  209. for (auto [l, r, j, c] : queries[m])
  210. ret[j] += c * st.query(l, r, (long long) m + 1);
  211.  
  212. for (int i=0; i<q; i++)
  213. cout << ret[i] << "\n";
  214.  
  215. return 0;
  216. }
  217.  
Success #stdin #stdout 0.01s 5540KB
stdin
4 3 3
2 3 2 2
1 1 6
1 3 3
1 3 6
2 2 2 3
1 4 1 3
4 4 2 3
stdout
180
825
8