开始写没dis 果断wa,看了别人分析,参考别人代码改了2个小时才改对,好难玩...
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N=10005,inf=1e9;
int val[N*4],lazy[N*4],level[N*4],dis[N*4];//dis表示最小升级的基数经验
int needk[15],tt,n,k,qw,cases=1;
void build(int l,int r,int rt){
val[rt]=0;level[rt]=1,lazy[rt]=0,dis[rt]=needk[1];
if(l==r)
return;
int m=(l+r)>>1;
build(lson);
build(rson);
}
inline void push_up(int rt){
val[rt]=max(val[rt*2],val[rt*2+1]);//最大经验
level[rt]=max(level[rt*2],level[rt*2+1]);//最大等级
dis[rt]=min(dis[rt*2],dis[rt*2+1]);//最小升级经验
}
inline void push_down(int rt){
if(lazy[rt]){
lazy[rt*2]+=lazy[rt];
dis[rt*2]-=lazy[rt];
val[rt*2]+=lazy[rt]*level[rt*2];
lazy[rt*2+1]+=lazy[rt];
dis[rt*2+1]-=lazy[rt];
val[rt*2+1]+=lazy[rt]*level[rt*2+1];
lazy[rt]=0;
}
}
void update(int a,int b,int c,int l,int r,int rt){
if(l==r){
val[rt]+=c*level[rt];
//val[rt]+=add;
while(val[rt]>=needk[level[rt]]){
level[rt]++;
}
dis[rt]=(needk[level[rt]]-val[rt]+level[rt]-1)/level[rt];//还需纯经验
//printf("--%d is %d %d %d %d\n",l,val[rt],level[rt],dis[rt]);
return;
}
if(a<=l&&b>=r){
if(c>=dis[rt]){//经验够升级
push_down(rt);
int m=(l+r)/2;
update(a,b,c,lson);
update(a,b,c,rson);
push_up(rt);
}
else{
val[rt]+=c*level[rt];
dis[rt]-=c;
lazy[rt]+=c;
}
return;
}
push_down(rt);
int m=(l+r)>>1;
if(a<=m)
update(a,b,c,lson);
if(b>m)
update(a,b,c,rson);
push_up(rt);
}
int query(int a,int b,int l,int r,int rt){
if(a<=l&&b>=r){
//printf("%d-%d is %d--\n",l,r,val[rt]);
return val[rt];
}
push_down(rt);
int m=(l+r)>>1,rst=0;
if(a<=m)
rst=max(rst,query(a,b,lson));
if(b>m)
rst=max(rst,query(a,b,rson));
return rst;
}
int main(){
cin>>tt;
while(tt--){
printf("Case %d:\n",cases++);
cin>>n>>k>>qw;
needk[0]=0;needk[k]=inf;
for(int i=1;i<k;i++)
scanf("%d",&needk[i]);
build(1,n,1);
while(qw--){
char op;
cin>>op;
int a,b,c;
if(op=='W'){
scanf("%d %d %d",&a,&b,&c);
update(a,b,c,1,n,1);
}
else{
scanf("%d %d",&a,&b);
printf("%d\n",query(a,b,1,n,1));
}
}
printf("\n");
}
return 0;
}