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.
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.
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).
For each query, output the maximum Exp from li to ri.
Output a black line after each case.
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
25
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)
题解:
题意:
有n个英雄,k个等级,m总操作,一开始英雄等级1,经验0
操作‘W’+x,y,z表示x到y号的打一个经验为z的怪,然后经验计算公式为每个人的等级*怪的经验,达到了经验会升级
操作‘Q’询问区间最大的经验值
这题是看别人博客题解做出来的。。一开始完全不知道不同的人升级怎么处理,后来知道了一个很巧妙的思想,就是每次每个人的升级最小需要怪的经验数的计算:升级最小经验数=下一等级所需要的经验/当前等级并这个数向上取整,知道这个就好做了
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<math.h>
#include<string>
#include<stdio.h>
#include<queue>
#include<stack>
#include<map>
#include<deque>
#define M (t[k].l+t[k].r)/2
#define lson k*2
#define rson k*2+1
using namespace std;
const int INF=100861111;
struct node
{
int l,r;
int max_level;//区间内最大等级
int sum_exp;//区间最大经验总和
int min_expneed;//区间内升级所需怪的最小经验
int tag;//lazy tag
}t[10005*4];
int level[15];//存放各级所需的经验
int ceil(int x,int y)//表示x除以y的向上取整函数
{
int d=x/y;
if(x%y)d++;
return d;
}
void Build(int l,int r,int k)
{
t[k].l=l;
t[k].r=r;
t[k].tag=0;
t[k].sum_exp=0;
t[k].min_expneed=level[2];//初始所需要的经验数为2级所需从经验
t[k].max_level=1;
if(l==r)
return;
int mid=M;
Build(l,mid,lson);
Build(mid+1,r,rson);
}
void pushup(int k)//简单的区间合并
{
t[k].max_level=max(t[lson].max_level,t[rson].max_level);
t[k].sum_exp=max(t[lson].sum_exp,t[rson].sum_exp);
t[k].min_expneed=min(t[lson].min_expneed,t[rson].min_expneed);
}
void pushdown(int k)//向下更新
{
if(t[k].l==t[k].r)
return;
if(t[k].tag)
{
t[lson].tag+=t[k].tag;
t[rson].tag+=t[k].tag;
t[lson].min_expneed-=t[k].tag;
t[rson].min_expneed-=t[k].tag;
t[lson].sum_exp+=t[lson].max_level*t[k].tag;
t[rson].sum_exp+=t[rson].max_level*t[k].tag;
t[k].tag=0;
}
}
void update(int l,int r,int k,int e)
{
if(l<=t[k].l&&t[k].r<=r)//这里是精髓,如果在操作区间内的子区间
{
if(t[k].min_expneed>e)这个区间没人升级,更新后返回
{
t[k].tag+=e;
t[k].sum_exp+=t[k].max_level*e;
t[k].min_expneed-=e;
return;
}
else//有人升级,就要更新到升级的那个人
{
if(l==r)//单点
{
t[k].sum_exp+=e*t[k].max_level;
while(t[k].sum_exp>=level[t[k].max_level+1])//升级
{
t[k].max_level++;
}
t[k].min_expneed=ceil(level[t[k].max_level+1]-t[k].sum_exp,t[k].max_level);//这就是上面所说的最小需要经验数的算法
return;
}
}
}
pushdown(k);
int mid=M;
if(r<=mid)
update(l,r,lson,e);
else if(l>mid)
update(l,r,rson,e);
else
{
update(l,mid,lson,e);
update(mid+1,r,rson,e);
}
pushup(k);
}
int query(int l,int r,int k)
{
if(t[k].l==l&&t[k].r==r)
{
return t[k].sum_exp;
}
int mid=M;
pushdown(k);
if(r<=mid)
return query(l,r,lson);
else if(l>mid)
return query(l,r,rson);
else
{
return max(query(l,mid,lson),query(mid+1,r,rson));
}
}
int main()
{
int i,j,k,n,m,q,test,x,y,z,l;
char s[10];
scanf("%d",&test);
for(l=1;l<=test;l++)
{
scanf("%d%d%d",&n,&k,&q);
for(i=2;i<=k;i++)
scanf("%d",&level[i]);
level[k+1]=INF;//这里要赋值为inf,否则会错,因为不能继续升级了
Build(1,n,1);
printf("Case %d:\n",l);
for(i=0;i<q;i++)
{
scanf("%s",s);//%s可以跳掉空格和回车
if(s[0]=='W')
{
scanf("%d%d%d",&x,&y,&z);
update(x,y,1,z);
}
else
{
scanf("%d%d",&x,&y);
printf("%d\n",query(x,y,1));
}
}
printf("\n");
}
return 0;
}