比赛 |
cdcqの省选膜你赛 |
评测结果 |
AAAAAAAAAAAAAATTTTTT |
题目名称 |
新史「新幻想史 -现代史-」 |
最终得分 |
70 |
用户昵称 |
Menci |
运行时间 |
15.455 s |
代码语言 |
C++ |
内存使用 |
6.63 MiB |
提交时间 |
2017-04-11 11:52:08 |
显示代码纯文本
- #include <cstdio>
- // #include <cassert>
- #include <algorithm>
-
- const int MAXN = 50000;
- const int MAXM = 50000;
-
- enum Type {
- Query, Update
- };
-
- struct Triple {
- Type type;
-
- // x: The index in operate sequence
- // y: The input 'time'
- int x, y, l, r;
-
- // For update
- int delta;
- bool applied;
-
- // For query
- long long *ans;
-
- Triple() {}
- 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) {}
- 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) {}
-
- bool operator<(const Triple &other) const {
- return x < other.x;
- }
-
- void print() {
- if (type == Update) printf("Update(%d, %d, [%d, %d], %d)\n", x, y, l, r, delta);
- else printf("Query(%d, %d, [%d, %d])\n", x, y, l, r);
- }
- } a[MAXN + MAXM + 1];
-
- struct SegT {
- int l, r, mid;
- SegT *lc, *rc;
- long long sum, tag;
-
- SegT(int pos) : l(pos), r(pos), mid(pos), lc(NULL), rc(NULL), sum(0), tag(0) {}
- 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) {}
-
- void maintain() {
- sum = lc->sum + rc->sum;
- }
-
- void pushDown() {
- if (tag) {
- lc->cover(tag);
- rc->cover(tag);
- tag = 0;
- }
- }
-
- void cover(long long delta) {
- sum += delta * (r - l + 1);
- tag += delta;
- }
-
- void update(int l, int r, long long delta) {
- if (l > this->r || r < this->l) return;
- else if (l <= this->l && r >= this->r) cover(delta);
- else pushDown(), lc->update(l, r, delta), rc->update(l, r, delta), maintain();
- }
-
- long long query(int l, int r) {
- if (l > this->r || r < this->l) return 0;
- else if (l <= this->l && r >= this->r) return sum;
- else return pushDown(), lc->query(l, r) + rc->query(l, r);
- }
-
- static SegT *build(int l, int r) {
- if (l == r) return new SegT(l);
- else {
- int mid = l + (r - l) / 2;
- return new SegT(l, r, build(l, mid), build(mid + 1, r));
- }
- }
- } *seg;
-
- inline void cdq(Triple *l, Triple *r) {
- /*
- puts("");
- for (Triple *p = l; p <= r; p++) p->print();
- */
- if (l == r) return;
-
- Triple *mid = l + (r - l) / 2;
-
- cdq(l, mid);
- cdq(mid + 1, r);
-
- static Triple tmp[MAXN + MAXM + 1];
- for (Triple *p1 = l, *p2 = mid + 1, *p = tmp; p <= tmp + (r - l); p++) {
- if (p1 <= mid && (p2 > r || p1->y <= p2->y)) {
- *p = *p1++;
- if (p->type == Update) {
- seg->update(p->l, p->r, p->delta);
- p->applied = true;
- // printf("seg->update([%d, %d], %d)\n", p->l, p->r, p->delta);
- }
- } else {
- *p = *p2++;
- if (p->type == Query) *p->ans += seg->query(p->l, p->r);
- }
- }
-
- for (Triple *p = l, *q = tmp; p <= r; p++, q++) {
- *p = *q;
- if (p->applied) {
- p->applied = false;
- seg->update(p->l, p->r, -p->delta);
- // printf("seg->update([%d, %d], %d)\n", p->l, p->r, -p->delta);
- }
- }
-
- // for (int i = 1; i <= 5; i++) assert(seg->query(i, i) == 0);
- }
-
- int main() {
- freopen("cdcq_a.in", "r", stdin);
- freopen("cdcq_a.out", "w", stdout);
-
- int n, m;
- scanf("%d %d", &n, &m);
-
- seg = SegT::build(1, n);
-
- int cnt = 0;
- for (int i = 1; i <= n; i++) {
- int x;
- scanf("%d", &x);
-
- ++cnt;
- a[cnt] = Triple(cnt, 0, i, i, x);
- }
-
- static long long ans[MAXM + 1];
- int qCnt = 0;
- for (int i = 1; i <= m; i++) {
- char s[2];
- scanf("%s", s);
-
- if (*s == 'Q') {
- int l, r, time;
- scanf("%d %d %d", &l, &r, &time);
-
- ++qCnt;
-
- ++cnt;
- a[cnt] = Triple(cnt, time, l, r, &ans[qCnt]);
- } else {
- int l1, r1, delta1, l2, r2, delta2, time;
- scanf("%d %d %d %d %d %d %d", &l1, &r1, &delta1, &l2, &r2, &delta2, &time);
-
- ++cnt;
- a[cnt] = Triple(cnt, time, l1, r1, -delta1);
- ++cnt;
- a[cnt] = Triple(cnt, time, l2, r2, delta2);
- }
- }
-
- std::sort(a + 1, a + cnt + 1);
-
- cdq(a + 1, a + cnt);
-
- for (int i = 1; i <= qCnt; i++) printf("%lld\n", ans[i]);
- }