用线段树保存区间最大经验值,最大级别,最小升级系数,和lazy标记。若区间内有hero要升级,则更新下去。否则直接更新区间信息。
思路是参照下面的大牛:
http://blog.csdn.net/weiguang_123/article/details/8095362
View Code
1 #include <stdio.h> 2 #define lson l,m,rt<<1 3 #define rson m+1,r,rt<<1|1 4 #define maxn 10005 5 int n,k,m; 6 int level[15]={ 7 0,0 8 }; 9 struct node 10 { 11 int level,dis,exp,c; 12 }setree[maxn<<2]; 13 int max(int a,int b) 14 { 15 return a>b?a:b; 16 } 17 int min(int a,int b) 18 { 19 return a<b?a:b; 20 } 21 void build(int l,int r,int rt) 22 { 23 setree[rt].exp=0; 24 setree[rt].dis=level[2]; 25 setree[rt].level=1; 26 setree[rt].c=0; 27 if(l==r) 28 return; 29 int m=(l+r)>>1; 30 build(lson); 31 build(rson); 32 } 33 void pushdown(int rt) 34 { 35 if(setree[rt].c){ 36 setree[rt<<1].dis-=setree[rt].c; 37 setree[rt<<1].c+=setree[rt].c; 38 setree[rt<<1].exp+=setree[rt<<1].level*setree[rt].c; 39 40 setree[rt<<1|1].dis-=setree[rt].c; 41 setree[rt<<1|1].c+=setree[rt].c; 42 setree[rt<<1|1].exp+=setree[rt<<1|1].level*setree[rt].c; 43 44 setree[rt].c=0; 45 } 46 } 47 void pushup(int rt) 48 { 49 setree[rt].exp=max(setree[rt<<1].exp,setree[rt<<1|1].exp); 50 setree[rt].level=max(setree[rt<<1].level,setree[rt<<1|1].level); 51 setree[rt].dis=min(setree[rt<<1].dis,setree[rt<<1|1].dis); 52 } 53 void update(int l,int r,int rt,int L,int R,int c) 54 { 55 if(l==r){ 56 setree[rt].exp+=setree[rt].level*c; 57 for(int i=2;i<=k;i++) 58 if(setree[rt].exp>=level[i]) 59 setree[rt].level=i; 60 setree[rt].dis=(level[setree[rt].level+1]-setree[rt].exp)/setree[rt].level; 61 if((level[setree[rt].level+1]-setree[rt].exp)%setree[rt].level!=0) 62 setree[rt].dis++; 63 return; 64 } 65 if(L<=l&&r<=R){ 66 if(setree[rt].dis>c){ 67 setree[rt].exp+=setree[rt].level*c; 68 setree[rt].dis-=c; 69 setree[rt].c+=c; 70 return; 71 } 72 } 73 pushdown(rt); 74 int m=(l+r)>>1; 75 if(L<=m) 76 update(lson,L,R,c); 77 if(R>m) 78 update(rson,L,R,c); 79 pushup(rt); 80 } 81 int query(int l,int r,int rt,int L,int R) 82 { 83 if(L<=l&&r<=R) 84 return setree[rt].exp; 85 pushdown(rt); 86 int m=(l+r)>>1; 87 int ret=0; 88 if(L<=m) 89 ret=query(lson,L,R); 90 if(R>m) 91 ret=max(ret,query(rson,L,R)); 92 return ret; 93 } 94 int main() 95 { 96 int t,cas=1; 97 scanf("%d",&t); 98 while(t--){ 99 scanf("%d%d%d",&n,&k,&m); 100 for(int i=2;i<=k;i++) 101 scanf("%d",level+i); 102 level[k+1]=1000000010; 103 build(1,n,1); 104 printf("Case %d:\n",cas++); 105 while(m--){ 106 char op[10]; 107 int a,b; 108 scanf("%s%d%d",op,&a,&b); 109 if(op[0]=='W'){ 110 int c; 111 scanf("%d",&c); 112 update(1,n,1,a,b,c); 113 } 114 else 115 printf("%d\n",query(1,n,1,a,b)); 116 } 117 puts(""); 118 } 119 return 0; 120 }