比赛 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]);
}