比赛 cdcqの省选膜你赛 评测结果 AAAAAAAAAAAAAATTTTTT
题目名称 新史「新幻想史 -现代史-」 最终得分 70
用户昵称 Menci 运行时间 15.455 s
代码语言 C++ 内存使用 6.63 MiB
提交时间 2017-04-11 11:52:08
显示代码纯文本
  1. #include <cstdio>
  2. // #include <cassert>
  3. #include <algorithm>
  4.  
  5. const int MAXN = 50000;
  6. const int MAXM = 50000;
  7.  
  8. enum Type {
  9. Query, Update
  10. };
  11.  
  12. struct Triple {
  13. Type type;
  14.  
  15. // x: The index in operate sequence
  16. // y: The input 'time'
  17. int x, y, l, r;
  18.  
  19. // For update
  20. int delta;
  21. bool applied;
  22.  
  23. // For query
  24. long long *ans;
  25.  
  26. Triple() {}
  27. Triple(int x, int y, int l, int r, int delta) : type(Update), x(x), y(y), l(l), r(r), delta(delta), applied(false), ans(NULL) {}
  28. Triple(int x, int y, int l, int r, long long *ans) : type(Query), x(x), y(y), l(l), r(r), delta(0), applied(false), ans(ans) {}
  29.  
  30. bool operator<(const Triple &other) const {
  31. return x < other.x;
  32. }
  33.  
  34. void print() {
  35. if (type == Update) printf("Update(%d, %d, [%d, %d], %d)\n", x, y, l, r, delta);
  36. else printf("Query(%d, %d, [%d, %d])\n", x, y, l, r);
  37. }
  38. } a[MAXN + MAXM + 1];
  39.  
  40. struct SegT {
  41. int l, r, mid;
  42. SegT *lc, *rc;
  43. long long sum, tag;
  44.  
  45. SegT(int pos) : l(pos), r(pos), mid(pos), lc(NULL), rc(NULL), sum(0), tag(0) {}
  46. SegT(int l, int r, SegT *lc, SegT *rc) : l(l), r(r), mid(l + (r - l) / 2), lc(lc), rc(rc), sum(0), tag(0) {}
  47.  
  48. void maintain() {
  49. sum = lc->sum + rc->sum;
  50. }
  51.  
  52. void pushDown() {
  53. if (tag) {
  54. lc->cover(tag);
  55. rc->cover(tag);
  56. tag = 0;
  57. }
  58. }
  59.  
  60. void cover(long long delta) {
  61. sum += delta * (r - l + 1);
  62. tag += delta;
  63. }
  64.  
  65. void update(int l, int r, long long delta) {
  66. if (l > this->r || r < this->l) return;
  67. else if (l <= this->l && r >= this->r) cover(delta);
  68. else pushDown(), lc->update(l, r, delta), rc->update(l, r, delta), maintain();
  69. }
  70.  
  71. long long query(int l, int r) {
  72. if (l > this->r || r < this->l) return 0;
  73. else if (l <= this->l && r >= this->r) return sum;
  74. else return pushDown(), lc->query(l, r) + rc->query(l, r);
  75. }
  76.  
  77. static SegT *build(int l, int r) {
  78. if (l == r) return new SegT(l);
  79. else {
  80. int mid = l + (r - l) / 2;
  81. return new SegT(l, r, build(l, mid), build(mid + 1, r));
  82. }
  83. }
  84. } *seg;
  85.  
  86. inline void cdq(Triple *l, Triple *r) {
  87. /*
  88. puts("");
  89. for (Triple *p = l; p <= r; p++) p->print();
  90. */
  91. if (l == r) return;
  92.  
  93. Triple *mid = l + (r - l) / 2;
  94.  
  95. cdq(l, mid);
  96. cdq(mid + 1, r);
  97. static Triple tmp[MAXN + MAXM + 1];
  98. for (Triple *p1 = l, *p2 = mid + 1, *p = tmp; p <= tmp + (r - l); p++) {
  99. if (p1 <= mid && (p2 > r || p1->y <= p2->y)) {
  100. *p = *p1++;
  101. if (p->type == Update) {
  102. seg->update(p->l, p->r, p->delta);
  103. p->applied = true;
  104. // printf("seg->update([%d, %d], %d)\n", p->l, p->r, p->delta);
  105. }
  106. } else {
  107. *p = *p2++;
  108. if (p->type == Query) *p->ans += seg->query(p->l, p->r);
  109. }
  110. }
  111.  
  112. for (Triple *p = l, *q = tmp; p <= r; p++, q++) {
  113. *p = *q;
  114. if (p->applied) {
  115. p->applied = false;
  116. seg->update(p->l, p->r, -p->delta);
  117. // printf("seg->update([%d, %d], %d)\n", p->l, p->r, -p->delta);
  118. }
  119. }
  120.  
  121. // for (int i = 1; i <= 5; i++) assert(seg->query(i, i) == 0);
  122. }
  123.  
  124. int main() {
  125. freopen("cdcq_a.in", "r", stdin);
  126. freopen("cdcq_a.out", "w", stdout);
  127.  
  128. int n, m;
  129. scanf("%d %d", &n, &m);
  130.  
  131. seg = SegT::build(1, n);
  132.  
  133. int cnt = 0;
  134. for (int i = 1; i <= n; i++) {
  135. int x;
  136. scanf("%d", &x);
  137.  
  138. ++cnt;
  139. a[cnt] = Triple(cnt, 0, i, i, x);
  140. }
  141.  
  142. static long long ans[MAXM + 1];
  143. int qCnt = 0;
  144. for (int i = 1; i <= m; i++) {
  145. char s[2];
  146. scanf("%s", s);
  147.  
  148. if (*s == 'Q') {
  149. int l, r, time;
  150. scanf("%d %d %d", &l, &r, &time);
  151.  
  152. ++qCnt;
  153.  
  154. ++cnt;
  155. a[cnt] = Triple(cnt, time, l, r, &ans[qCnt]);
  156. } else {
  157. int l1, r1, delta1, l2, r2, delta2, time;
  158. scanf("%d %d %d %d %d %d %d", &l1, &r1, &delta1, &l2, &r2, &delta2, &time);
  159.  
  160. ++cnt;
  161. a[cnt] = Triple(cnt, time, l1, r1, -delta1);
  162. ++cnt;
  163. a[cnt] = Triple(cnt, time, l2, r2, delta2);
  164. }
  165. }
  166.  
  167. std::sort(a + 1, a + cnt + 1);
  168.  
  169. cdq(a + 1, a + cnt);
  170.  
  171. for (int i = 1; i <= qCnt; i++) printf("%lld\n", ans[i]);
  172. }