用线段树保存区间最大经验值,最大级别,最小升级系数,和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 }