
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
Case 1: 3 6 Case 2: 9 18 25HintCase 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)
很好的题,题目大意是有n个英雄,m个等级,q个操作,刚开始每个英雄都是等级1,经验0,下边m-1个整数,表示升每一级所需要的经验,下边跟q个操作,w a b c,区间【a,b】的英雄去打怪,获得的经验是英雄的等级*c,q a b,查询区间【a,b】中英雄最大的经验
ac代码
#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f3f
#define max(a,b) (a>b?a:b)
#define min(a,b) (a>b?b:a)
struct s
{
__int64 level,maxnum,flag,need;
void init()
{
level=1;
maxnum=0;
flag=0;
}
void fun(__int64 val)
{
maxnum+=level*val;
need-=val;
flag+=val;
}
}node[10005<<2];
__int64 need[15];
void pushdown(int tr)
{
if(node[tr].flag)
{
node[tr<<1].fun(node[tr].flag);
node[tr<<1|1].fun(node[tr].flag);
node[tr].flag=0;
}
}
void pushup(int tr)
{
node[tr].maxnum=max(node[tr<<1].maxnum,node[tr<<1|1].maxnum);
node[tr].level=max(node[tr<<1].level,node[tr<<1|1].level);
node[tr].need=min(node[tr<<1].need,node[tr<<1|1].need);
}
void build(int l,int r,int tr)
{
node[tr].init();
node[tr].need=need[2];
if(l==r)
return;
int mid=(l+r)>>1;
build(l,mid,tr<<1);
build(mid+1,r,tr<<1|1);
}
void update(int L,int R,int l,int r,int tr,int val)
{
if(L<=l&&r<=R)
{
if(val>=node[tr].need)
{
if(l==r)
{
__int64 &now=node[tr].level;
node[tr].maxnum+=now*val;
while(node[tr].maxnum>=need[now+1])
now++;
__int64 temp=need[now+1]-node[tr].maxnum;
node[tr].need=temp/now+(temp%now!=0);
}
else
{
pushdown(tr);
int mid=(l+r)>>1;
if(L<=mid)
update(L,R,l,mid,tr<<1,val);
if(R>mid)
update(L,R,mid+1,r,tr<<1|1,val);
pushup(tr);
}
}
else
{
node[tr].fun(val);
}
return;
}
pushdown(tr);
int mid=(l+r)>>1;
if(L<=mid)
update(L,R,l,mid,tr<<1,val);
if(R>mid)
update(L,R,mid+1,r,tr<<1|1,val);
pushup(tr);
}
__int64 query(int L,int R,int l,int r,int tr)
{
if(L<=l&&r<=R)
{
return node[tr].maxnum;
}
pushdown(tr);
int mid=(l+r)>>1;
__int64 temp1=0,temp2=0;
if(L<=mid)
temp1=query(L,R,l,mid,tr<<1);
if(R>mid)
temp2=query(L,R,mid+1,r,tr<<1|1);
pushup(tr);
return max(temp1,temp2);
}
int main()
{
int t,c=0;
scanf("%d",&t);
while(t--)
{
int n,m,q,i,j;
scanf("%d%d%d",&n,&m,&q);
for(i=2;i<=m;i++)
scanf("%I64d",&need[i]);
need[m+1]=INF;
build(1,n,1);
printf("Case %d:\n",++c);
while(q--)
{
char op[5];
scanf("%s",op);
if(op[0]=='W')
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
update(a,b,1,n,1,c);
}
else
{
int a,b;
scanf("%d%d",&a,&b);
printf("%I64d\n",query(a,b,1,n,1));
}
}
printf("\n");
}
}版权声明:本文为博主原创文章,未经博主允许不得转载。
HDOJ 题目3954 Level up(线段树去见面更新区间查询)
原文:http://blog.csdn.net/yu_ch_sh/article/details/48104541