感觉太神了,研究了一天,不过有时候有些题目还是要思考上一段时间才能弄明白题目是怎么做的,貌似对延迟标记又有了更深的理解。
题意:n个英雄, 每个英雄初始经验为0, 初始等级为1, 通过打妖怪可以获得经验从而提高等级, 两种操作
1 给l, r区间内的英雄加上 k * x的经验
2 询问l, r区间的最大经验值
分析: 一开始想的太简单了,只是简单的给一段区间做延迟标记, 等到要查询再更新下去,这样的话向下更新的时候登记可能已经变了,所以是不对的, 因为每次经验的获得值为k * x,与等级有关系, 所以要另外开一个域表示该区间可以升级的最小经验基数,一旦加入的经验基数 >= 最小经验基数, 就往下更新, 直到叶子节点或不能更新为止
#include
#include
#include
using namespace std;
struct node {
int x, y, z;
}a[10010 << 2];
int col[10010 << 2], v[20];
int ql, qr, x;
int n, k, m;
char s[10];
void pushup(int o) {
a[o].x = max(a[2*o].x, a[2*o+1].x);
a[o].y = max(a[2*o].y, a[2*o+1].y);
a[o].z = min(a[2*o].z, a[2*o+1].z);
}
void pushdown(int o) {
a[2*o].y += a[2*o].x * col[o];
a[2*o].z -= col[o];
col[2*o] += col[o];
a[2*o+1].y += a[2*o+1].x * col[o];
a[2*o+1].z -= col[o];
col[2*o+1] += col[o];
col[o] = 0;
}
void construct(int o, int l, int r) {
a[o].x = 1;
a[o].y = 0;
a[o].z = v[2];
col[o] = 0;
if(l == r) return ;
int m = (l + r) >> 1;
construct(2*o, l, m);
construct(2*o+1, m+1, r);
}
void update(int o, int l, int r) {
if(l == r) {
a[o].y += a[o].x * x;
int id = 1;
for(int i = 2; i <= k; i++)
if(a[o].y >= v[i]) id = i;
a[o].x = id;
if(id == k) a[o].z = (1 << 31) - 1;
else {
a[o].z = (v[id+1] - a[o].y) / id;
if((v[id+1]-a[o].y) % id) a[o].z++;
}
return;
}
if(ql <= l && qr >= r) {
if(x >= a[o].z) {
if(col[o]) pushdown(o);
int m = (l + r) >> 1;
update(2*o, l, m);
update(2*o+1, m+1, r);
pushup(o);
}
else {
a[o].y += a[o].x * x;
a[o].z -= x;
col[o] += x;
}
return ;
}
if(col[o]) pushdown(o);
int m = (l + r) >> 1;
if(ql <= m) update(2*o, l, m);
if(qr > m) update(2*o+1, m+1, r);
pushup(o);
}
int query(int o, int l, int r) {
if(ql <= l && qr >= r) return a[o].y;
if(col[o]) pushdown(o);
int m = (l + r) >> 1;
int ans = 0;
if(ql<= m) ans = max(ans, query(2*o, l, m));
if(qr > m) ans = max(ans, query(2*o+1, m+1, r));
return ans;
}
int main() {
int T, ca = 1;
scanf("%d", &T);
while(T--) {
scanf("%d%d%d", &n, &k, &m);
for(int i = 2; i <= k; i++) scanf("%d", &v[i]);
construct(1, 1, n);
printf("Case %d:\n", ca++);
while(m--) {
scanf("%s", s);
if(s[0] == 'W') {
scanf("%d%d%d", &ql, &qr, &x);
update(1, 1, n);
}
else {
scanf("%d%d", &ql, &qr);
printf("%d\n", query(1, 1, n));
}
}
puts("");
}
return 0;
}