线段树 lazy标记 因为k很小所以我们可以维护k个等级下的最大经验
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#define INF (int)(1e9)
#define maxn 10100
#define Lson l, mid, rt << 1
#define Rson mid + 1, r, rt << 1 | 1
using namespace std;
typedef long long ll;
int n, k, q;
int Max[15][maxn << 2], now[maxn << 2], fab[maxn << 2], mark[maxn << 2];
int need[15];
void push_down(int rt) {
if (mark[rt]) {
mark[rt << 1] += mark[rt];
mark[rt << 1 | 1] += mark[rt];
for (int i = 1; i <= k; ++ i) {
if (Max[i][rt << 1] != -1) Max[i][rt << 1] += i*mark[rt];
if (Max[i][rt << 1 | 1] != -1) Max[i][rt << 1 | 1] += i*mark[rt];
}
mark[rt] = 0;
}
}
void push_up(int rt) {
for (int i = 1; i <= k; ++ i) {
Max[i][rt] = max(Max[i][rt << 1], Max[i][rt << 1 | 1]);
}
}
void level_up(int i, int l, int r, int rt) {
if (l == r) {
while (i < k && Max[i][rt] >= need[i]) {
Max[i+1][rt] = Max[i][rt];
Max[i][rt] = -1;
++ i;
}
return;
}
push_down(rt);
int mid = (l + r) >> 1;
if (Max[i][rt << 1] >= need[i]) level_up(i, Lson);
if (Max[i][rt << 1 | 1] >= need[i]) level_up(i, Rson);
push_up(rt);
}
void update(int L, int R, int c, int l, int r, int rt) {
if (L <= l && r <= R) {
mark[rt] += c;
for (int i = k; i >= 1; -- i) {
if (Max[i][rt] != -1) Max[i][rt] += c*i;
if (i < k && Max[i][rt] >= need[i]) {
level_up(i, l, r, rt);
}
}
return;
}
push_down(rt);
int mid = (l + r) >> 1;
if (L <= mid)
update(L, R, c, Lson);
if (R > mid)
update(L, R, c, Rson);
push_up(rt);
}
int query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) {
for (int i = k; i >= 1; -- i) {
if (Max[i][rt] != -1) return Max[i][rt];
}
}
push_down(rt);
int ret = 0;
int mid = (l + r) >> 1;
if (L <= mid) {
ret = max(ret, query(L, R, Lson));
}
if (R > mid) {
ret = max(ret, query(L, R, Rson));
}
return ret;
}
int main() {
int t, now = 0;
scanf("%d", &t);
while (t --) {
memset(mark, 0, sizeof(mark));
memset(Max, -1, sizeof(Max));
memset(Max[1], 0, sizeof(Max[1]));
printf("Case %d:\n", ++ now);
scanf("%d%d%d", &n, &k, &q);
for (int i = 1; i < k; ++ i) {
scanf("%d", &need[i]);
}
char c[10];
int l, r, p;
while (q --) {
scanf("%s", c);
if (c[0] == 'W') {
scanf("%d%d%d", &l, &r, &p);
update(l,r,p,1,n,1);
}
else if (c[0] == 'Q') {
scanf("%d%d", &l, &r);
printf("%d\n", query(l,r,1,n,1));
}
}
puts("");
}
}