题意:
有n 个英雄,初始化为等级1,0经验。告诉你升每一级所需经验数。
两种操作:
1. 将[L,R]中的英雄来杀能力值为e 的怪物, 这些英雄涨 等级*e 的经验。
2. 询问区间中最大经验。
思路:
线段树, 维护一个区间中最大等级, 升级所需要最小经验,最大经验数。
其实挺暴力的。
我们想一想 什么时候 可以加懒惰标记?
杀死怪物后,区间内没有人升级, 那么我们可以直接懒惰标记 不用在往下传了。
否则就往下传 直到 为一个区间为一个结点。
有一个小技巧。就是维护升级所需最小经验时, 我们可以用 (升级经验 - 当前经验) 除以 当前等级 ,向上取整。
因为一个区间每个英雄等级不一样, 打怪后 得到的经验也不同, 但是这样做 就忽略了等级的影响, 直接操作e即可。(很巧妙= =)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 10000 + 10;
int le[12],ks;
const int inf = 0x3f3f3f3f;
struct node{
int l,r;
int minsj_exp; /// 升级所需最小经验
int max_level; /// 最大等级
int flag; /// 懒惰标记
int sum_exp; /// 最大经验
}nod[maxn<<2];
int n,K,q;
void pushup(int o){
if (nod[o].l == nod[o].r)return;
int lson = o << 1;
int rson = o << 1 | 1;
nod[o].minsj_exp = min(nod[lson].minsj_exp, nod[rson].minsj_exp);
nod[o].max_level = max(nod[lson].max_level, nod[rson].max_level);
nod[o].sum_exp = max(nod[lson].sum_exp , nod[rson].sum_exp);
}
void pushdown(int o){
int l = nod[o].l;
int r = nod[o].r;
if (l == r) return;
int lson = o << 1;
int rson = o << 1 | 1;
if (nod[o].flag){
nod[lson].flag += nod[o].flag;
nod[rson].flag += nod[o].flag;
nod[lson].minsj_exp -= nod[o].flag;
nod[rson].minsj_exp -= nod[o].flag;
nod[lson].sum_exp += nod[o].flag * nod[lson].max_level;
nod[rson].sum_exp += nod[o].flag * nod[rson].max_level;
nod[o].flag = 0;
}
}
void build(int l,int r,int o){
nod[o].l = l;
nod[o].r = r;
nod[o].minsj_exp = le[2];
nod[o].max_level = 1;
nod[o].flag = 0;
nod[o].sum_exp = 0;
if (l == r){
return;
}
int m = l + r >> 1;
build(l,m,o<<1);
build(m+1,r,o<<1|1);
pushup(o);
}
int up(int x,int y){ ///计算x/y 向上取整。
int ans = x / y;
if (x % y) ans++;
return ans;
}
void update(int L,int R,int e,int l,int r,int o){
if (L <= l && r <= R){
if (nod[o].minsj_exp > e){
nod[o].flag += e;
nod[o].minsj_exp -= e;
nod[o].sum_exp += nod[o].max_level * e;
return;
}
else {
if (l == r){
nod[o].sum_exp += nod[o].max_level * e;
while(nod[o].sum_exp >= le[nod[o].max_level + 1])++nod[o].max_level;
nod[o].minsj_exp = up(le[nod[o].max_level+1] - nod[o].sum_exp , nod[o].max_level);
return;
}
}
}
pushdown(o);
int m = l + r >> 1;
if (m >= L){
update(L,R,e,l,m,o<<1);
}
if (m < R){
update(L,R,e,m+1,r,o<<1|1);
}
pushup(o);
}
int query(int L,int R,int l,int r,int o){
if (L <= l && r <= R){
return nod[o].sum_exp;
}
int ans = 0;
int m = l + r >> 1;
pushdown(o);
if (m >= L){
ans = max(ans, query(L,R,l,m,o<<1));
}
if (m < R){
ans = max(ans, query(L,R,m+1,r,o<<1|1));
}
return ans;
}
char cmd[23];
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d %d %d", &n, &K, &q);
for (int i = 2; i <= K; ++i){
scanf("%d",&le[i]);
}
le[K+1] = inf;
build(1,n,1);
printf("Case %d:\n",++ks);
while(q--){
scanf("%s", cmd);
if (cmd[0] == 'W'){
int l,r,ei;
scanf("%d %d %d",&l, &r, &ei);
update(l,r,ei,1,n,1);
}
else {
int l,r;
scanf("%d %d",&l, &r);
printf("%d\n", query(l,r,1,n,1));
}
}
putchar('\n');
}
return 0;
}
Level up
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4325 Accepted Submission(s): 1204
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.
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).
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.
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 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)
Author
NotOnlySuccess
Source
Recommend