比赛 cdcqの省选膜你赛 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 新史「新幻想史 -现代史-」 最终得分 100
用户昵称 LoveYayoi 运行时间 6.318 s
代码语言 C++ 内存使用 12.14 MiB
提交时间 2017-04-11 20:15:06
显示代码纯文本
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <vector>
#include <queue>
#include <time.h>
#define eps 10e-7
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define rep0(j,n) for(int j=0;j<n;++j)
#define rep1(j,n) for(int j=1;j<=n;++j)
#define pb push_back
#define set0(n) memset(n,0,sizeof(n))
#define ll long long
//#define OJ
using namespace std;
int read() {
	char c = getchar(); int f = 1, x = 0;
	while (!isdigit(c)) { if (c == '-') f = -1; c = getchar(); }
	while (isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
	return f*x;
}
char get_ch() {
	char c = getchar();
	while (!isalpha(c)) c = getchar();
	return c;
}
const int MAXINT = 50010;
ll ans[MAXINT];
int n, m, cnt = 0, cnt_q = 0;
struct node {
	int lb, rb;
	ll sum, tag;
	node *c[2];
	node(int _lb, int _rb) :lb(_lb), rb(_rb),tag(0),sum(0) {}
	node() :tag(0), sum(0) {
	}
	int check(int l, int r) {
		if (l <= lb&&r >= rb) return 1;
		if (l >= rb || r <= lb) return 0;
		return -1;
	}
	void add_tag(ll v) {
		sum += v*(rb - lb);
		tag += v;
	}
	void pushdown() {
		c[0]->add_tag(tag);
		c[1]->add_tag(tag);
		tag = 0;
	}
	void pushup() {
		sum = c[0]->sum + c[1]->sum;
	}
};
struct seg_tree {
	node mp[MAXINT * 4];
	int cnt;
	node *rt;
	seg_tree() {
		cnt = 0;
	}
	node* new_node(int l, int r) {
		mp[cnt] = node(l, r);
		return &mp[cnt++];
	}
	void make_tree(int l, int r) {
		rt = new_node(l, r);
		_make_tree(rt, l, r);
	}
	void _make_tree(node *p, int l, int r) {
		if (r - l == 1) {
			p->sum = 0;
			return;
		}
		p->c[0] = new_node(l, (l + r) / 2);
		p->c[1] = new_node((l + r) / 2, r);
		_make_tree(p->c[0], l, (l + r) / 2);
		_make_tree(p->c[1], (l + r) / 2, r);
		p->pushup();
	}
	ll seg_query(int l, int r) {
		return _seg_query(rt, l, r);
	}
	ll _seg_query(node *p, int l, int r) {
		int tp = p->check(l, r);
		if (tp == 1) return p->sum;
		if (tp == 0) return 0;
		p->pushdown();
		return _seg_query(p->c[0], l, r) + _seg_query(p->c[1], l, r);
	}
	void seg_add(int l, int r, int v) {
		_seg_add(rt, l, r, v);
	}
	void _seg_add(node *p, int l, int r, int v) {
		int tp = p->check(l, r);
		if (tp == 1) { p->add_tag(v); return; }
		if (tp == 0) return;
		_seg_add(p->c[0], l, r, v); _seg_add(p->c[1], l, r, v);
		p->pushdown();
		p->pushup();
	}
}seg;
struct op {
	int tp, t, no, q_no, l, r, v;
	op(int _t, int _no, int _l, int _r, int _v) {
		tp = 1;
		t = _t;
		no = _no;
		l = _l;
		r = _r;
		v = _v;
	}
	op() {}
	op(int _t, int _no, int _l, int _r) {
		tp = 0;
		t = _t;
		q_no = cnt_q;
		no = _no;
		l = _l;
		r = _r;
	}
}ops[200010];
bool cmpt(const op &a, const op &b) {
	return a.t == b.t ? a.tp > b.tp:a.t < b.t;
}
bool cmpno(const op &a, const op &b) {
	return a.no == b.no ? a.tp > b.tp : a.no < b.no;
}
void cdq(int l, int r) {
	if (r - l == 1) {
		return;
	}
	cdq(l, (l + r) / 2);
	cdq((l + r) / 2, r);
	sort(ops + l, ops + (l + r) / 2, cmpt);
	sort(ops + (l + r) / 2, ops + r, cmpt);
	int i = l;
	int j = (l + r) / 2;
	for (; j < r; j++) {
		if (ops[j].tp == 1) continue;
		for (; i < (l + r) / 2 && ops[i].t <= ops[j].t; i++) {
			if (ops[i].tp == 0) continue;
			seg.seg_add(ops[i].l, ops[i].r, ops[i].v);
		}
		ans[ops[j].q_no] += seg.seg_query(ops[j].l, ops[j].r);
	}
	i = l;
	j = (l + r) / 2;
	for (; j < r; j++) {
		if (ops[j].tp == 1) continue;
		for (; i < (l + r) / 2 && ops[i].t <= ops[j].t; i++) {
			if (ops[i].tp == 0) continue;
			seg.seg_add(ops[i].l, ops[i].r, -ops[i].v);
		}
	}
	sort(ops + l, ops + r, cmpt);
}
void get_input() {
	n = read(); m = read();
	seg.make_tree(0, n);
	char tp;
	int t, l, r, v, l1, r1, v1;
	rep0(i, n) {
		t = read();
		ops[cnt++] = op(-1, -1, i, i + 1, t);
	}
	rep0(i, m) {
		tp = get_ch();
		if (tp == 'Q') {
			l = read(); r = read(); t = read();
			ops[cnt++] = op(t, i, l - 1, r);
			cnt_q++;
		}
		else {
			l = read(); r = read(); v = read(); l1 = read(); r1 = read(); v1 = read(); t = read();
			ops[cnt++] = op(t, i, l - 1, r, -v);
			ops[cnt++] = op(t, i, l1 - 1, r1, v1);
		}
	}
}
void work() {
	cdq(0, cnt);
	rep0(i, cnt_q) {
		printf("%lld\n", ans[i]);
	}
}
int main() {
	freopen("cdcq_a.in", "r", stdin);
	freopen("cdcq_a.out", "w", stdout);
	get_input();
	work();
	return 0;
}