hdu 3954 Level up

Level up

Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2381    Accepted Submission(s): 648


Problem Description
Level up is the task of all online games. It's very boooooooooring. There is only level up in those games, except level up.
In a online game, there are N heroes numbered id from 1 to N, each begins with level 1 and 0 Experience. They need to kill monsters to get Exp and level up.

There are many waves of monsters, each wave, the heroes with id from li to ri will come to kill monsters and those hero with level k will get ei*k Exp. If one hero's Exp reach Needk then the hero level up to level k immediately.
After some waves, I will query the maximum Exp from li to ri.
Now giving the information of each wave and Needk, please tell me the answer of my query.
 

Input
The first line is a number T(1<=T<=30), represents the number of case. The next T blocks follow each indicates a case.
The first line of each case contains three integers N(1<=N<=10000), K(2<=K<=10) and QW(1<=QW<=10000)each represent hero number, the MAX level and querys/waves number.
Then a line with K -1 integers, Need2, Need3...Needk.(1 <= Need2 < Need3 < ... < Needk <= 10000).
Then QW lines follow, each line start with 'W' contains three integers li ri ei (1<=li<=ri<=N , 1<=ei<=10000); each line start with 'Q' contains two integers li ri (1<=li<=ri<=N).
 

Output
For each case, output the number of case in first line.(as shown in the sample output)
For each query, output the maximum Exp from li to ri.
Output a black line after each case.
 

Sample Input
2 3 3 5 1 2 W 1 1 1 W 1 2 1 Q 1 3 W 1 3 1 Q 1 3 5 5 8 2 10 15 16 W 5 5 9 W 3 4 5 W 1 1 2 W 2 3 2 Q 3 5 W 1 3 8 Q 1 2 Q 3 5
 

Sample Output
Case 1: 3 6 Case 2: 9 18 25
Hint
Case 1: At first ,the information of each hero is 0(1),0(1),0(1) [Exp(level)] After first wave, 1(2),0(1),0(1); After second wave, 3(3),1(2),0(1); After third wave, 6(3),3(3),1(2); Case 2: The information of each hero finally: 18(5) 18(5) 25(5) 5(2) 9(2)
 

Author
NotOnlySuccess
 

Source
 

Recommend
lcy

在每个节点定义了一个max数组,记录这颗子树下面,每个等级的人的最高经验,下次如果有经验加在这个区间里面,
而这段区间里面的人加上这个经验都不会升级,那就可以暂时把经验存在这个节点而不用下传了,只有当经验加下去,
人要升级了,才往下传


#include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <algorithm> using namespace std; #define N 11111 #define lson l,m,k<<1 #define rson m+1,r,k<<1|1 struct node { int max[11]; int add; }st[N<<2]; int lv[11]; int Kth; void build(int l,int r,int k) { st[k].add=0; st[k].max[1]=0; int i; for(i=2;i<=Kth;i++) st[k].max[i]=-1; if(l==r) return; int m=(l+r)>>1; build(lson); build(rson); } void up(int &k) { int i; for(i=1;i<=Kth;i++) { st[k].max[i]=max(st[k<<1].max[i],st[k<<1|1].max[i]); } } void down(int &k) { st[k<<1].add+=st[k].add; st[k<<1|1].add+=st[k].add; int i; for(i=1;i<=Kth;i++) { //开始这里写成了 if else 、、、那样分支语句就只有一个出口了、、、明显有问题 if(st[k<<1].max[i]!=-1) { st[k<<1].max[i]+=i*st[k].add; } if(st[k<<1|1].max[i]!=-1) { st[k<<1|1].max[i]+=i*st[k].add; } } st[k].add=0; } void Down(int l,int r,int k) { if(l==r) { int i; for(i=1;i<=Kth;i++) if(st[k].max[i]!=-1) break; int t=st[k].max[i]; st[k].max[i]=-1; for(i=Kth;i>=1;i--) if(t>=lv[i]) { st[k].max[i]=t; break; } return ; } down(k); int i; bool flag=0; for(i=1;i<Kth;i++) if(st[k].max[i]>=lv[i+1]) { flag=1; break; } if(flag) { int m=(l+r)>>1; Down(lson); Down(rson); up(k); } } int L,R,ad; void update(int l,int r,int k) { if(L<=l&&R>=r) { int i; bool flag=0; st[k].add+=ad; for(i=1;i<=Kth;i++) if(st[k].max[i]!=-1) { st[k].max[i]+=i*ad; if(i<Kth&&st[k].max[i]>=lv[i+1]) flag=1; } if(flag) Down(l,r,k); return ; } down(k); int m=(l+r)>>1; if(L<=m) update(lson); if(R>m) update(rson); up(k); } int query(int l,int r,int k) { if(L<=l&&R>=r) { int i; for(i=Kth;i>=1;i--) if(st[k].max[i]!=-1) return st[k].max[i]; } down(k); int m=(l+r)>>1; int lm=-1,rm=-1; if(L<=m) lm=query(lson); if(R>m) rm=query(rson); return max(lm,rm); } int main() { int T,t=1; scanf("%d",&T); int i,n,q; char op[3]; while(T--) { printf("Case %d:\n",t++); scanf("%d %d %d",&n,&Kth,&q); for(i=2;i<=Kth;i++) scanf("%d",&lv[i]); build(1,n,1); while(q--) { scanf("%s",op);//这里要这样写,因为题目可能出现多余空格啥的、坑你 if(op[0]=='W') { scanf("%d %d %d",&L,&R,&ad); update(1,n,1); } else { scanf("%d %d",&L,&R); printf("%d\n",query(1,n,1)); } } printf("\n"); } return 0; }

posted on 2012-10-24 23:31  江财小子  阅读(399)  评论(0编辑  收藏  举报