HDU 3954 Level up(线段树)

来源:互联网 发布:网络投资平台 编辑:程序博客网 时间:2024/06/13 22:27

HDU 3954 Level up

题目链接

题意:k个等级,n个英雄,每个等级升级有一定经验,每次两种操作,一个区间加上val,这样区间内英雄都获得当前等级*val的经验,另一个操作询问区间经验最大值

思路:由于等级少,所以每个结点用Max[10]记录下每个等级的最大值,如果有一个升级就一直找到底,因为一个英雄升级最多10次,所以这个操作最多就10W次可以接受,剩下就是普通的区间修改区间查询的延迟操作了

代码:

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 10005;const int M = 11;int t, n, k, qw, need[M];#define lson(x) ((x<<1)+1)#define rson(x) ((x<<1)+2)struct Node {int l, r, Max[M], add;bool cover;} node[N * 4];void build(int l, int r, int x = 0) {node[x].l = l; node[x].r = r;memset(node[x].Max, -1, sizeof(node[x].Max));node[x].Max[1] = 0;node[x].add = 0;node[x].cover = false;if (l == r) return;int mid = (l + r) / 2;build(l, mid, lson(x));build(mid + 1, r, rson(x));}bool judge(int x, int v) {for (int i = 1; i < k; i++) {if (node[x].Max[i] == -1) continue;if (node[x].Max[i] + i * v >= need[i + 1]) return true;}return false;}void pushup(int x) {node[x].cover = (node[lson(x)].cover && node[rson(x)].cover);for (int i = 1; i <= k; i++)node[x].Max[i] = max(node[lson(x)].Max[i], node[rson(x)].Max[i]);}void pushdown(int x) {if (node[x].add) {node[lson(x)].add += node[x].add;node[rson(x)].add += node[x].add;for (int i = 1; i <= k; i++) {if (node[lson(x)].Max[i] != -1)node[lson(x)].Max[i] += node[x].add * i;if (node[rson(x)].Max[i] != -1)node[rson(x)].Max[i] += node[x].add * i;}node[x].add = 0;}}void add(int l, int r, int v, int x = 0) {if (node[x].l >= l && node[x].r <= r && (node[x].cover || !judge(x, v))) {node[x].add += v;for (int i = 1; i <= k; i++) {if (node[x].Max[i] == -1) continue;node[x].Max[i] += i * v;}return;}if (node[x].l == node[x].r) {int have;for (int i = 1; i < k; i++) {if (node[x].Max[i] != -1) {have = node[x].Max[i] + i * v;break;}}memset(node[x].Max, -1, sizeof(node[x].Max));for (int i = 2; i <= k; i++) {if (have < need[i]) {node[x].Max[i - 1] = have;return;}}node[x].Max[k] = have;node[x].cover = true;return;}int mid = (node[x].l + node[x].r) / 2;pushdown(x);if (l <= mid) add(l, r, v, lson(x));if (r > mid) add(l, r, v, rson(x));pushup(x);}int query(int l, int r, int x = 0) {if (node[x].l >= l && node[x].r <= r) {for (int i = k; i >= 1; i--) {if (node[x].Max[i] == -1) continue;return node[x].Max[i];}}int mid = (node[x].l + node[x].r) / 2;int ans = 0;pushdown(x);if (l <= mid) ans = max(ans, query(l, r, lson(x)));if (r > mid) ans = max(ans, query(l, r, rson(x)));pushup(x);return ans;}int main() {int cas = 0;scanf("%d", &t);while (t--) {printf("Case %d:\n", ++cas);scanf("%d%d%d", &n, &k, &qw);for (int i = 2; i <= k; i++)scanf("%d", &need[i]);build(1, n);char op[15];int a, b, c;while (qw--) {scanf("%s%d%d", op, &a, &b);if (op[0] == 'W') {scanf("%d", &c);add(a, b, c);} else printf("%d\n", query(a, b));}printf("\n");}return 0;}


0 0
原创粉丝点击