hdu 3954--线段树
http://acm.hdu.edu.cn/showproblem.php?pid=3954
题意:有N个英雄,每个英雄的初始等级为1,初始经验为0,有K个等级,QW个操作。接下来一行中有K-1个数值,代表升到等级2,等级3……所要达到的经验。接下来的QW行里,每行是一个操作,操作有两类,(1)"l r e",代表区间[l,r]里的每个英雄将得到e乘以他的等级的经验。(2)"l r",表示查询区间[l,r]里经验最大值。
思路:这题因为加的经验跟等级有关,所以不能用普通的惰性标记。应该往什么时候区间内加的经验是一样的方向思考???刚开始思考的时候是想着区间内都满级的时候加的经验就一样了,但是这样写依旧超时。。后来网上搜了一下,忽略了区间内如果没有英雄升级时加的经验也是一样多了,然后再加上这个判断条件就Ok了。一开始写挫了,无限超时,不过我对线段树的惰性标记倒是又增加了不少认识。方法:用sjmin存区间内升级需要的最少经验,djmax存区间内的最大等级,flag作为惰性标记,如果没有英雄升级的话可以暂时不用把经验往下传,Max存区间内的最大经验。而因为每个英雄的增加经验跟等级有关,所以sjmin的计算方法是用距离下一等级的经验除以当前等级,然后向上取整。
代码:

1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 #define lson l,m,rt<<1 5 #define rson m+1,r,rt<<1|1 6 #define maxn 55555 7 int Max[maxn<<2],flag[maxn<<2],sjmin[maxn<<2],djmax[maxn<<2],jy[15]; 8 int max(int a,int b) 9 { 10 return a>b?a:b; 11 } 12 int min(int a,int b) 13 { 14 return a<b?a:b; 15 } 16 void Pushup(int rt) 17 { 18 Max[rt]=max(Max[rt<<1],Max[rt<<1|1]); 19 sjmin[rt]=min(sjmin[rt<<1],sjmin[rt<<1|1]); 20 djmax[rt]=max(djmax[rt<<1],djmax[rt<<1|1]); 21 } 22 void Pushdown(int rt) 23 { 24 flag[rt<<1]+=flag[rt]; 25 flag[rt<<1|1]+=flag[rt]; 26 Max[rt<<1]+=djmax[rt<<1]*flag[rt]; 27 Max[rt<<1|1]+=djmax[rt<<1|1]*flag[rt]; 28 sjmin[rt<<1]-=flag[rt]; 29 sjmin[rt<<1|1]-=flag[rt]; 30 flag[rt]=0; 31 } 32 void build(int l,int r,int rt) 33 { 34 Max[rt]=0; 35 djmax[rt]=1; 36 sjmin[rt]=jy[2]; 37 flag[rt]=0; 38 if(l==r) 39 return ; 40 int m=(l+r)>>1; 41 build(lson); 42 build(rson); 43 } 44 void update(int L,int R,int w,int l,int r,int rt) 45 { 46 if(L<=l&&r<=R) 47 { 48 if(sjmin[rt]>w) 49 { 50 Max[rt]+=djmax[rt]*w; 51 flag[rt]+=w; 52 sjmin[rt]-=w; 53 return ; 54 } 55 else if(l==r) 56 { 57 Max[rt]+=djmax[rt]*w; 58 while(Max[rt]>=jy[djmax[rt]+1]) 59 djmax[rt]++; 60 sjmin[rt]=(jy[djmax[rt]+1]-Max[rt])/djmax[rt]+((jy[djmax[rt]+1]-Max[rt])%djmax[rt]!=0); 61 return ; 62 } 63 } 64 Pushdown(rt); 65 int m=(l+r)>>1; 66 if(L<=m) update(L,R,w,lson); 67 if(R>m) update(L,R,w,rson); 68 Pushup(rt); 69 } 70 int query(int L,int R,int l,int r,int rt) 71 { 72 if(L<=l&&r<=R) 73 return Max[rt]; 74 Pushdown(rt); 75 int m=(l+r)>>1; 76 int ret=0; 77 if(L<=m) ret=max(ret,query(L,R,lson)); 78 if(R>m) ret=max(ret,query(L,R,rson)); 79 return ret; 80 } 81 int main() 82 { 83 int t,n,m,dj,cas=1; 84 scanf("%d",&t); 85 while(t--) 86 { 87 scanf("%d %d %d",&n,&dj,&m); 88 for(int i=2;i<=dj;i++) 89 scanf("%d",&jy[i]); 90 jy[1]=0;jy[i]=1<<30; 91 build(1,n,1); 92 char ch[10]; 93 int a,b,c; 94 printf("Case %d:\n",cas++); 95 while(m--) 96 { 97 scanf("%s",ch); 98 if(ch[0]=='W') 99 { 100 scanf("%d %d %d",&a,&b,&c); 101 update(a,b,c,1,n,1); 102 } 103 else 104 { 105 scanf("%d %d",&a,&b); 106 printf("%d\n",query(a,b,1,n,1)); 107 } 108 } 109 puts(""); 110 } 111 return 0; 112 }
posted on 2013-02-21 12:01 acoderworld 阅读(325) 评论(0) 收藏 举报
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
【推荐】AI 的力量,开发者的翅膀:欢迎使用 AI 原生开发工具 TRAE
【推荐】2025 HarmonyOS 鸿蒙创新赛正式启动,百万大奖等你挑战