http://acm.hdu.edu.cn/showproblem.php?pid=3954
终于AC了,这个题目思路是没问题,但是我就是出现各种各样的细节错误,写线段树都有很多细节要注意的,尤其是带有延迟标记的线段树,各个变量之间数值的传递思路一定要清晰才行……
每个节点记录的变量:
level : 表示该节点表示区间中的点的最大等级
Max : 表示该节点表示区间中的点的最大经验值
need: 表示该节点表示区间中的点要升级的最小需要的怪物的ei
延迟标记: col
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int inf=0x3fffffff;
const int maxn=10010;
typedef long long ll;
ll col[maxn<<2],Max[maxn<<2],need[maxn<<2],level[maxn<<2],ned[12];
void build(int l,int r,int rt)
{
col[rt]=Max[rt]=0;
level[rt]=1;
need[rt]=ned[2];
if(l==r) return;
int m=(l+r)>>1;
build(lson);
build(rson);
}
void pushdown(int rt)
{
if(col[rt]){
col[rt<<1]+=col[rt];
col[rt<<1|1]+=col[rt];
Max[rt<<1]+=level[rt<<1]*col[rt];
Max[rt<<1|1]+=level[rt<<1|1]*col[rt];
need[rt<<1|1]-=col[rt];
need[rt<<1]-=col[rt];
col[rt]=0;
}
}
void pushup(int rt)
{
Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
level[rt]=max(level[rt<<1],level[rt<<1|1]);
need[rt]=min(need[rt<<1],need[rt<<1|1]);
}
void update(int L,int R,int val,int l,int r,int rt)
{
//cout<<l<<" "<<r<<" "<<rt<<" "<<need[rt]<<endl;
if(L<=l&&R>=r){
if(val>=need[rt]){
if(l==r){
Max[rt]+=val*level[rt];
ll &now=level[rt];
while(Max[rt]>=ned[now+1]) now++;
need[rt]=(ned[now+1]-Max[rt])/now + ((ned[now+1]-Max[rt])%now!=0); //我写成了 need[rt]=(ned[now+1]-ned[now])/now + ((ned[now+1]-ned[now])%now!=0);
}else {
pushdown(rt);
int m=(l+r)>>1;
update(L,R,val,lson);
update(L,R,val,rson);
pushup(rt); //当时写忘了,pushup
}
}else{
col[rt]+=val;
Max[rt]+=level[rt]*val;
need[rt]-=val;
}
return;
}
pushdown(rt);
int m=(l+r)>>1;
if(L<=m) update(L,R,val,lson);
if(R>m) update(L,R,val,rson);
pushup(rt);
}
ll query(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r) return Max[rt];
pushdown(rt);
int m=(l+r)>>1;
ll ret1=0,ret2=0;
if(L<=m) ret1=query(L,R,lson);
if(R>m) ret2=query(L,R,rson);
pushup(rt);
return max(ret1,ret2);
}
int main()
{
char ord[5];
int n,m,l,r,a,ca,cas=1,k;
scanf("%d",&ca);
while(ca--)
{
scanf("%d%d%d",&n,&k,&m);
ned[1]=0;
for(int i=2;i<=k;i++) scanf("%d",&ned[i]);
ned[k+1]=inf;
build(1,n,1);
printf("Case %d:\n",cas++);
while(m--){
scanf("%s",ord);
if(ord[0]=='W'){
scanf("%d%d%d",&l,&r,&a);
update(l,r,a,1,n,1);
}else{
scanf("%d%d",&l,&r);
printf("%I64d\n",query(l,r,1,n,1));
}
}
puts("");
}
return 0;
}