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;
}
历时一整天总算搞定了,大错误没有,小错误一大堆,心都碎了,只能说线段树太让人蛋疼了。两百行的代码,检查起来相当蛋疼,尤其是测试数据,各种小错误都可以过,坑爹啊。
两种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;
}
相关文章推荐
- poj 3667 hotel - 线段树-区间更新-延迟标记
- HDU 1698 Just a Hook(线段树 + Lazy Tag(延迟更新))
- HDU-4533:威威猫系列故事——晒被子(线段树延迟更新+推公式)
- POJ3468 线段树(区间更新,区间求和,延迟标记)
- FZU Problem 2105 Digits Count线段树之延迟更新(插线取线)
- 区间更新 区间和查询 带有延迟标记 线段树 hdu1698; 附:csa 区间加值,维护最大值
- codevs 1082 线段树练习 3 区间更新+延迟标记
- HDU 1698 Just a Hook(线段树延迟更新)
- 线段树专题#4_蒟蒻训练历程记录_HDU1698_ 延迟标记、区间更新
- hdu 5023 线段树延迟更新+状态压缩
- POJ 3468 A Simple Problem with Integers(线段树 + Lazy Tag(延迟更新))
- 【线段树延迟更新】Codeforces Round #104 (Div. 1) E
- poj4047(线段树+延迟更新)
- 线段树区间更新模板(lazy延迟标记)(1698)
- zoj 1610 Count the Colors(线段树延迟更新)
- hdu 5023 线段树延迟更新+状态压缩
- 线段树区间更新区间求和(转延迟标记精讲)
- [线段树]poj3667 Hotel(区间合并、更新、延迟/懒惰标记
- Poj3468(线段树延迟更新)
- hdu1698 Just a Hook 线段树更新延迟标记