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