您的位置:首页 > 其它

hdu3954 线段树延迟更新

2012-10-27 22:07 141 查看
延迟最小升级经验值/每级经验最大值,只能说思想屌爆啦!

历时一整天总算搞定了,大错误没有,小错误一大堆,心都碎了,只能说线段树太让人蛋疼了。两百行的代码,检查起来相当蛋疼,尤其是测试数据,各种小错误都可以过,坑爹啊。

两种AC代码如下:



延迟最小升级经验值:


#include<stdio.h>
#include<string.h>

const int size=11111;
const int INF=((1<<30)-1);

int k,need[12],lazy[size<<2],li[size<<2],ri[size<<2];
int exp[size<<2],lev[size<<2],md[size<<2];

int Max(int a1,int a2) { return a1>a2?a1:a2; }

int Min(int a1,int a2) { return a1<a2?a1:a2; }

int upgrade(int i,int tmp)
{
while (i<k)
{
if (tmp<need[i]) break;
else i++;
}
return i;
}

void PushUp(int rt)
{
md[rt]=Min(md[rt<<1],md[rt<<1|1]);
exp[rt]=Max(exp[rt<<1],exp[rt<<1|1]);
lev[rt]=Max(lev[rt<<1],lev[rt<<1|1]);
}

void build(int rt,int l,int r)
{
li[rt]=l;ri[rt]=r;
lazy[rt]=exp[rt]=0;
lev[rt]=1;
md[rt]=need[1];
if (l==r) return ;
int m=(l+r)>>1;
build(rt<<1,l,m);
build(rt<<1|1,m+1,r);
}

void PushDown(int rt)
{
if (lazy[rt]>0)
{
if (li[rt]==ri[rt])
{
lev[rt]=upgrade(lev[rt],exp[rt]);
md[rt]=need[lev[rt]]-exp[rt];
return ;
}
int t1=rt<<1,t2=rt<<1|1;
int v=lazy[rt];
lazy[rt]=0;
lazy[t1]+=v; lazy[t2]+=v;
exp[t1]+=lev[t1]*v; exp[t2]+=lev[t2]*v;
if (lev[t1]*v>=md[t1]) PushDown(t1);
else md[t1]-=lev[t1]*v;
if (lev[t2]*v>=md[t2]) PushDown(t2);
else md[t2]-=lev[t2]*v;
PushUp(rt);
}
}

void update(int rt,int l,int r,int L,int R,int v)
{
if (L<=l&&r<=R)
{
bool flag=false;
lazy[rt]+=v;
exp[rt]+=lev[rt]*v;
if (lev[rt]*v>=md[rt]) PushDown(rt);
else md[rt]-=lev[rt]*v;
return ;
}
PushDown(rt);
int m=(l+r)>>1;
if (L<=m) update(rt<<1,l,m,L,R,v);
if (R>m) update(rt<<1|1,m+1,r,L,R,v);
PushUp(rt);
}

int query(int rt,int l,int r,int L,int R)
{
if (L<=l&&r<=R) return exp[rt];
PushDown(rt);
int m=(l+r)>>1,ans=0;
if (L<=m) ans=Max(ans,query(rt<<1,l,m,L,R));
if (R>m) ans=Max(ans,query(rt<<1|1,m+1,r,L,R));
return ans;
}

int main()
{
int n,q,a,b,v,T,ncase=0;
scanf("%d",&T);
char str[5];
while(T--)
{
scanf("%d %d %d",&n,&k,&q);
for(int i=1; i<k; i++)scanf("%d",&need[i]);
need[k]=INF;
build(1,1,n);
printf("Case %d:\n",++ncase);
for(int i=0; i<q; i++)
{
scanf("%s",&str);
if(str[0]=='W')
{
scanf("%d%d%d",&a,&b,&v);
update(1,1,n,a,b,v);
}
else
{
scanf("%d%d",&a,&b);
printf("%d\n",query(1,1,n,a,b));
}
}
printf("\n");
}
return 0;
}


每级经验最大值:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

const int N = 11111;
const int INF=((1<<30)-1);

struct node
{
int l,r;
int lazy;
int val[12];
} tre[N<<2];

int le[12],k;

int upgrade(int lev,int ep)
{
while (lev<k)
if (ep<le[lev]) break;
else lev++;
return lev;
}

int Max(int a,int b)
{
return a>b?a:b;
}

void PushUp(int rt)
{
for(int i=1; i<=k; i++)
tre[rt].val[i]=Max(tre[rt<<1].val[i],tre[rt<<1|1].val[i]);
}

void build(int rt,int l,int r)
{
tre[rt].l=l;
tre[rt].r=r;
memset(tre[rt].val,-1,sizeof(tre[rt].val));
tre[rt].lazy=tre[rt].val[1]=0;
if(l==r) return ;
int m=(r+l)>>1;
build(rt<<1,l,m);
build(rt<<1|1,m+1,r);
}

void PushDown(int rt)
{
if (tre[rt].l>=tre[rt].r) return ;
if(tre[rt].lazy>0)
{
int t1=rt<<1;
int t2=t1|1;
int flag1=0,flag2=0;
int v=tre[rt].lazy;
tre[t1].lazy+=v;
tre[t2].lazy+=v;
tre[rt].lazy=0;
for(int i=k; i>0; i--)
{
if(tre[t1].val[i]>=0)
{
tre[t1].val[i]+=i*v;
if(tre[t1].val[i]>=le[i])
{
int tmp=upgrade(i,tre[t1].val[i]);
tre[t1].val[tmp]=Max(tre[t1].val[tmp],tre[t1].val[i]);
tre[t1].val[i]=-1;
flag1=1;
}
}
if(tre[t2].val[i]>=0)
{
tre[t2].val[i]+=i*v;
if(tre[t2].val[i]>=le[i])
{
int tmp=upgrade(i,tre[t2].val[i]);
tre[t2].val[tmp]=Max(tre[t2].val[tmp],tre[t2].val[i]);
tre[t2].val[i]=-1;
flag2=1;
}
}
}
if(flag1) PushDown(t1);
if(flag2) PushDown(t2);
PushUp(rt);
}
}

void update(int rt,int l,int r,int L,int R,int v)
{
if(L<=l&&r<=R)
{
int flag=0;
for (int i=k; i>0; i--)
{
if (tre[rt].val[i]>=0)
{
tre[rt].val[i]+=i*v;
if (tre[rt].val[i]>=le[i]&&i!=k)
{
int tmp=upgrade(i,tre[rt].val[i]);
tre[rt].val[tmp]=Max(tre[rt].val[tmp],tre[rt].val[i]);
tre[rt].val[i]=-1;
flag=1;
}
}
}
tre[rt].lazy+=v;
if (flag) PushDown(rt);
return ;
}
PushDown(rt);
int m=(r+l)>>1;
if(L<=m)update(rt<<1,l,m,L,R,v);
if(R>m) update(rt<<1|1,m+1,r,L,R,v);
PushUp(rt);
}

int query(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
for (int i=k; i>0; i--)
if (tre[rt].val[i]>=0) return tre[rt].val[i];
PushDown(rt);
int m=(r+l)>>1;
int ans=0;
if(L<=m)ans=Max(ans,query(rt<<1,l,m,L,R));
if(R>m) ans=Max(ans,query(rt<<1|1,m+1,r,L,R));
return ans;
}

int main()
{
int t,n,m,a,b,v,T=0;
scanf("%d",&t);
char temp[5];
while(t--)
{
scanf("%d%d%d",&n,&k,&m);
build(1,1,n); le[k]=INF;
for(int i=1; i<k; i++)scanf("%d",&le[i]);
printf("Case %d:\n",++T);
while (m--)
{
scanf("%s",&temp);
if(temp[0]=='W')
{
scanf("%d%d%d",&a,&b,&v);
update(1,1,n,a,b,v);
}
else
{
scanf("%d%d",&a,&b);
printf("%d\n",query(1,1,n,a,b));
}
}
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: