HDU 3954 Level up
来源:互联网 发布:nginx过滤ip 编辑:程序博客网 时间:2024/05/17 09:25
题目地址
题意:就是打怪升级,告诉你升到该级的经验是多少,然后你获得的经验是你的等级乘以该怪所给的经验,求出一段区间中的最大经验值
思路:用结构体分别记录该段区间的最大经验值以及想要升级的最小经验基数(就是这个基数乘以最大等级会使得能够升级)还有该区间的最大等级,当你给的经验都不能让最小经验基数升级的话就自己更新这段区间以及延迟标记就好了,如果能升级再向下更新,直到找到完整升级的那个区间,其他的就是正常线段树了。
PS:解释下为什么要用最小经验基数的原因,因为有可能出现级数和所需经验不匹配的情况(因为他每次得到的经验是和当前等级绑定的),所以最好的方式是用所需经验和当前等级的比值排序,这才能更好的表示出当前区域最先升级的所要的经验。
#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <stack>#include <cmath>#include <cstdio>#include <algorithm>#define N 15010#define LL long long#define inf 0x3f3f3f3f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1using namespace std;const LL mod = 1e9 + 7;const double eps = 1e-9;int num[N];int n, q, m;struct node { int level, mx, need, lazy;//最高的等级,经验,升级所需要的最少的经验基数,延迟标记 void init() { level = 1; mx = 0, lazy = 0; need = num[2]; } void find(LL val) { mx += level*val; need -= val; lazy += val; }}sum[N << 2];//线段树主体struct Segment__Tree { int x, y; void pushUp(int ans) { sum[ans].mx = max(sum[ans << 1].mx, sum[ans << 1 | 1].mx); sum[ans].level = max(sum[ans << 1].level, sum[ans << 1 | 1].level); sum[ans].need = min(sum[ans << 1].need, sum[ans << 1 | 1].need); } void pushDown(int ans) { if (sum[ans].lazy) { sum[ans << 1].lazy += sum[ans].lazy; sum[ans << 1].mx += sum[ans].lazy*sum[ans << 1].level; sum[ans << 1].need -= sum[ans].lazy; sum[ans << 1 | 1].lazy += sum[ans].lazy; sum[ans << 1 | 1].mx += sum[ans].lazy*sum[ans << 1 | 1].level; sum[ans << 1 | 1].need -= sum[ans].lazy; } sum[ans].lazy = 0; } void build(int l, int r, int ans) { sum[ans].init(); if (l == r) { return; } int mid = (l + r) >> 1; build(lson); build(rson); } int solve(int l, int r, int ans) { if (l >= x&&r <= y) { return sum[ans].mx; } int mid = (l + r) >> 1; pushDown(ans); if (mid<x) { return solve(rson); } else if (mid >= y) { return solve(lson); } else { return max(solve(lson), solve(rson)); } } void updata(int l, int r, int ans, int nums) { if (l == r) { sum[ans].mx += nums*sum[ans].level; while (sum[ans].mx >= num[sum[ans].level + 1]) { sum[ans].level++; } sum[ans].need = (num[sum[ans].level + 1] - sum[ans].mx) / sum[ans].level + ((num[sum[ans].level + 1] - sum[ans].mx) % sum[ans].level != 0); return; } if (l >= x&&r <= y) { if (sum[ans].need > nums) { sum[ans].find(nums); } else { int mid = (l + r) / 2; pushDown(ans); updata(lson, nums); updata(rson, nums); pushUp(ans); } return; } int mid = (l + r) >> 1; pushDown(ans); if (mid<x) { updata(rson, nums); } else if (mid >= y) { updata(lson, nums); } else { updata(lson, nums); updata(rson, nums); } pushUp(ans); }};int main() { cin.sync_with_stdio(false); int c; char s; int T; Segment__Tree tree; cin >> T; for (int Case = 1; Case <= T; Case++) { cin >> n >> m >> q; num[1] = 0; for (int i = 2; i <= m; i++) { cin >> num[i]; } num[m + 1] = inf; tree.build(1, n, 1); cout << "Case " << Case << ":" << endl; while (q--) { cin >> s >> tree.x >> tree.y; if (s == 'Q') { cout << tree.solve(1, n, 1) << endl;; } else { cin >> c; tree.updata(1, n, 1, c); } } cout << endl; } return 0;}
阅读全文
0 0
- hdu 3954 Level up
- hdu 3954 Level up
- HDU-3954-Level up
- HDU 3954 Level up
- HDU 3954 Level up
- HDU 3954 level up 线段树
- HDU 3954 Level up(线段树)
- hdu 3954 Level up(线段树)
- hdu 3954 Level up (线段树)
- hdu 3954 Level up(线段树)
- HDU 3954 Level up(线段树)
- hdu 3954 Level up 线段树
- HDU 3954 Level up (线段树)
- hdu Level up
- HDU 5788 Level Up
- HDU 3954 Level up 2011 Alibaba Programming Contest 线段树
- 阿里巴巴2011公开赛1004 Level up HDU 3954 线段树
- hdu 3954 Level up(成段更新)
- Mongodb基本操作
- Springcloud学习(一)
- 辗转相除法、更相减损法、Stein算法
- TensorFlow学习——CIFAR-10(python实现数据可视化)
- 关于RecyclerView之纵向滚动(自己记录用)
- HDU 3954 Level up
- 在java Web中实现文件的上传下载
- 计算机百科
- window查看端口号对应的进程号
- HDU1285 确定比赛名次(拓扑排序)
- A
- 002_Hello,World
- 不想吃鸡#2
- 金蝶K3数据库表名对应及表说明