hdu 3954(区间更新)
来源:互联网 发布:mysql 更新字段加一 编辑:程序博客网 时间:2024/05/21 09:26
题意:有n个人,每个人初始等级是1,初始经验值是0,一共有K个等级,给出到达每个等级需要的经验值,然后有q个操作,W l r e把第l个人到第r个人的经验值都加上其对应的等级×e,Q l r询问l到r人中经验值的最大值。
题解:刚开始用单点修改把每个人经验值改掉,毫无疑问的超时了,然后就想怎么把每个人获得不同的经验值在区间表示,苦逼的想不出来,然后看了题解。。。因为要维护区间最大经验值,所以就维护一个最小到下一等级需要的经验值need,need[k] = (下一等级经验值-当前经验值) / 当前等级 + 余数 ,这样消除不同等级的人所加经验值的不同。
#include <cstdio>#include <cstring>#include <algorithm>#define ll long longusing namespace std;const int N = 10005;int level[N << 2], n, K, q;ll Exp[N << 2], need[N << 2], flag[N << 2], ex[15];void pushup(int k) { Exp[k] = max(Exp[k * 2], Exp[k * 2 + 1]); level[k] = max(level[k * 2], level[k * 2 + 1]); need[k] = min(need[k * 2], need[k * 2 + 1]);}void pushdown(int k) { if (flag[k]) { Exp[k * 2] += flag[k] * level[k * 2]; need[k * 2] -= flag[k]; flag[k * 2] += flag[k]; Exp[k * 2 + 1] += flag[k] * level[k * 2 + 1]; need[k * 2 + 1] -= flag[k]; flag[k * 2 + 1] += flag[k]; flag[k] = 0; }}void build(int k, int left, int right) { need[k] = ex[2]; Exp[k] = flag[k] = 0; level[k] = 1; if (left != right) { int mid = (left + right) / 2; build(k * 2, left, mid); build(k * 2 + 1, mid + 1, right); }}void modify(int k, int left, int right, int l, int r, ll v) { if (l <= left && right <= r) { if (v >= need[k]) { if (left == right) { Exp[k] += level[k] * v; while (Exp[k] >= ex[level[k] + 1]) level[k]++; ll temp = ex[level[k] + 1] - Exp[k]; need[k] = temp / level[k] + (temp % level[k] != 0); } else { pushdown(k); int mid = (left + right) / 2; if (l <= mid) modify(k * 2, left, mid, l, r, v); if (r > mid) modify(k * 2 + 1, mid + 1, right, l, r, v); pushup(k); } } else { Exp[k] += v * level[k]; need[k] -= v; flag[k] += v; } return; } pushdown(k); int mid = (left + right) / 2; if (l <= mid) modify(k * 2, left, mid, l, r, v); if (r > mid) modify(k * 2 + 1, mid + 1, right, l, r, v); pushup(k); return;}ll query(int k, int left, int right, int l, int r) { if (l <= left && right <= r) return Exp[k]; pushdown(k); int mid = (left + right) / 2; ll res = 0; if (l <= mid) res = max(res, query(k * 2, left, mid, l, r)); if (r > mid) res = max(res, query(k * 2 + 1, mid + 1, right, l, r)); pushup(k); return res;}int main() { int t, cas = 1; scanf("%d", &t); ex[1] = 0; while (t--) { scanf("%d%d%d", &n, &K, &q); for (int i = 2; i <= K; i++) scanf("%lld", &ex[i]); ex[K + 1] = (ll)(1 << 30); build(1, 1, n); char op[5]; int l, r; ll e; printf("Case %d:\n", cas++); while (q--) { scanf("%s%d%d", op, &l, &r); if (op[0] == 'W') { scanf("%lld", &e); modify(1, 1, n, l, r, e); } else { printf("%lld\n", query(1, 1, n, l, r)); } } printf("\n"); } return 0;}
0 0
- hdu 3954(区间更新)
- hdu 3954(线段树区间更新)
- HDU 3954 区间更新区间查询 打怪升级
- hdu 1698 区间更新
- hdu 4578(区间更新)
- hdu 4614(区间更新)
- hdu 4747(区间更新)
- hdu 4027(区间更新)
- hdu 1698 区间更新
- hdu-11992-更新区间
- hdu 4107 Gangster(区间更新)
- hdu 1698区间延迟更新
- HDU 1698 区间更新 求和
- HDU 4747 Mex 区间更新
- hdu 1698 简单区间更新
- hdu - 4325- Flowers - 区间更新,单点查询
- HDU 1698 区间更新线段树
- hdu 3308 线段树 区间更新 LICS
- 栈的应用之表达式求值(算符优先法)
- C++ string学习
- 最小树形图*
- JavaScript 调用 CSS 属性
- Hibernate教程 class2
- hdu 3954(区间更新)
- Java的clone方法 prototype
- 微信URL有效性验证
- django 注册、登录及第三方接口程序(1):基础知识
- CSS定位属性之间的相互作用
- Xfire Nested exception is org.codehaus.xfire.fault.XFireFault:Couldn't send message.
- 表达式的合法判断
- Java类中字段和方法的初始化顺序(包含static)
- Linux_Prgramming_Link_Library