hdu 3954 线段树 (标记)
Level up
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3973 Accepted Submission(s): 1104
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
25
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | /* hdu 3954 线段树 (标记) 给你n个人,然后打怪升级,如果当前人的等级为x,怪的经验为k,则这个人 可以得到x*k的经验。 然后k-1个数表示2-k即所需要的经验,假设你有leve[k]的经验,便能马上 升到k级。(最开始以为是k-1到k级要leve[k]的经验 TAT) 最开始只是记录的经验最大值MAX和add标记,然后更新最大值。 但是每次都要查找等级大小,感觉应该是TLE,但却一直WR.感觉很费解 然后借鉴了下别人的思路 新增了一个need和grade,即区间中升级所差经验的最小值,如果添加的经验小于 这个need,则更新这些标记即可.否则就找到那些需要升级的进行升级。 hhh-2016-03-22 22:48:41 */ #include <iostream> #include <cstdio> #include <cstring> using namespace std; #define lson (i<<1) #define rson ((i<<1)|1) typedef long long ll; int n,qw; int k; const int maxn = 10010; struct node { int l,r,grade; int Max; int add,need; int mid() { return (l+r)>>1; } } tree[maxn*10]; int leve[15]; void push_up( int i) { tree[i].Max = max(tree[lson].Max,tree[rson].Max); tree[i].grade = max(tree[lson].grade,tree[rson].grade); tree[i].need = min(tree[lson].need,tree[rson].need); } void fin_level( int cur) { for ( int i = tree[cur].grade; i < k; i++) { if (tree[cur].Max >= leve[i]) tree[cur].grade = i+1; } } void build( int l, int r, int i) { tree[i].l = l; tree[i].r = r; tree[i].Max = tree[i].add = 0; tree[i].need = leve[1]; tree[i].grade = 1; if (l == r) { return ; } int mid = tree[i].mid(); build(l,mid,lson); build(mid+1,r,rson); push_up(i); } void push_down( int i) { if (tree[i].add) { tree[lson].add += tree[i].add; tree[rson].add += tree[i].add; tree[lson].Max += tree[i].add*tree[lson].grade; tree[rson].Max += tree[i].add*tree[rson].grade; tree[lson].need -= tree[i].add; tree[rson].need -= tree[i].add; tree[i].add = 0; } } void Insert( int i, int l, int r, int val) { push_down(i); int mid = tree[i].mid(); if (tree[i].l == tree[i].r) { tree[i].Max += val*tree[i].grade; fin_level(i); tree[i].need = (leve[tree[i].grade]-tree[i].Max)/(tree[i].grade)+ ((leve[tree[i].grade]-tree[i].Max)%(tree[i].grade)!=0); return ; } else if (tree[i].l >= l && tree[i].r <= r) { if (tree[i].need > val) { tree[i].add += val; tree[i].need -= val; tree[i].Max += (ll)val*tree[i].grade; return ; } push_down(i); if (l <= mid)Insert(lson,l,r,val); if (r > mid)Insert(rson,l,r,val); push_up(i); return ; } if (l <= mid)Insert(lson,l,r,val); if (r > mid)Insert(rson,l,r,val); push_up(i); } int query( int i, int l, int r) { if (tree[i].l >= l && tree[i].r <= r) { return tree[i].Max; } push_down(i); int ma = 0; int mid = tree[i].mid(); if (l <= mid) ma =max(ma,query(lson,l,r)); if (r > mid) ma =max(ma,query(rson,l,r)); return ma; } int main() { int T,cas = 1; scanf ( "%d" ,&T); while (T--) { scanf ( "%d%d%d" ,&n,&k,&qw); for ( int i = 1; i < k; i++) scanf ( "%d" ,&leve[i]); build(1,n,1); leve[0] = 0; leve[k] = 1<<30; char ch[4]; int l,r; int val; printf ( "Case %d:\n" ,cas++); for ( int i = 1; i <=qw; i++) { scanf ( "%s" ,ch); if (ch[0] == 'Q' ) { scanf ( "%d%d" ,&l,&r); ll ma = query(1,l,r); printf ( "%I64d\n" ,ma); } if (ch[0] == 'W' ) { scanf ( "%d%d%d" ,&l,&r,&val); Insert(1,l,r,val); } } printf ( "\n" ); } return 0; } |
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 不到万不得已,千万不要去外包
· C# WebAPI 插件热插拔(持续更新中)
· 会议真的有必要吗?我们产品开发9年了,但从来没开过会
· 【译】我们最喜欢的2024年的 Visual Studio 新功能
· 如何打造一个高并发系统?