题目链接:点击查看

题目大意:给出 n 个武器及花费,m 个防具及花费,以及 k 个怪物及属性,每个怪物的属性同样有着攻击力,防御力以及价值,初始时可以选择一个武器以及一个防具,如果此时的攻击力大于怪物的攻击力,且防御力大于怪物的防御力,则可以打败这个怪物,并且获得其掉落的价值,现在问如何挑选初始时的武器可以使得收益最大化

题目分析:二维偏序的好题,补题的时候看到标签上写着数据结构,双指针和排序,以及这个题目攻击力和防御力的攻击范围都才1e6而不是1e9,加上对于每个怪物是否击败都有着两个维度的限制,所以不难想到要用二维偏序来解决,先对攻击力排序,这样就能忽略掉攻击力带来的限制了,因为题目的数据范围都在1e6以内,所以我们在读入时将其映射到数轴上,而不是开一个二维数组保存,这样就相当于对攻击力进行桶排序了,可以优化掉快速排序 logn 的时间复杂度,最后每个怪物的属性还是需要开一个三个变量的结构体保存,想一下如何将防御力映射到线段树上去,因为击败某个怪物的条件是攻击力以及防御力都必须严格大于该怪物,而对攻击力排序已经可以忽略掉攻击力带来的影响了,剩下的我们可以将线段树的每个端点视为防御力的具体数值,而每个端点所保存的数值是利润,若要查询最终答案,只需要查询一下每次线段树中的最大值,再减去当前遍历到的武器的花费就是答案了,至于更新线段树也是比较好想的,因为对于某个怪物的防御力而言,只有大于其防御力的防具才能够打败这个怪物,那么只需要对区间[ x + 1 , n ]都加上这个怪物的价值就好了,其中 x 为这个怪物的防御力,线段树初始化为每点防御力的价格,因为在将防御力映射到数轴上之后,会有很多地方的花费是 0 ,但并不代表此时的花费为 0 ,所以需要预处理一下,如果某个点的花费为 0 ,那么这个点可能会被比这个点大的防具所包含,所以倒着维护一下就好了,还有一个小细节就是可能防御力较高的防具花费会比较低,就像样例给出的数据一样,这个时候还需要维护一下最小值

还有一些小细节就是,因为题目的数据刚好卡到int,所以数据范围不会爆int,不过在设置无穷小的时候,因为极限情况会到达-2e9,所以要把无穷小设的小一些

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e5+100;const int M=1e6+100;struct node
{int x,y,val;bool operator<(const node& a)const{return x<a.x;}
}c[N];int a[M],b[M];struct Node
{int l,r,mmax,lazy;
}tree[M<<2];void pushup(int k)
{tree[k].mmax=max(tree[k<<1].mmax,tree[k<<1|1].mmax);
}void pushdown(int k)
{if(tree[k].lazy){int lz=tree[k].lazy;tree[k].lazy=0;tree[k<<1].lazy+=lz;tree[k<<1|1].lazy+=lz;tree[k<<1].mmax+=lz;tree[k<<1|1].mmax+=lz;}
}void build(int k,int l,int r)
{tree[k].l=l;tree[k].r=r;tree[k].lazy=0;if(l==r){tree[k].mmax=-b[l];return;}int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);pushup(k);
}void update(int k,int l,int r,int val)
{if(tree[k].r<l||tree[k].l>r)return;if(tree[k].l>=l&&tree[k].r<=r){tree[k].mmax+=val;tree[k].lazy+=val;return;}pushdown(k);update(k<<1,l,r,val);update(k<<1|1,l,r,val);pushup(k);
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int n,m,k;scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=n;i++){int pos,val;scanf("%d%d",&pos,&val);if(a[pos])a[pos]=min(a[pos],val);elsea[pos]=val;}for(int i=1;i<=m;i++){int pos,val;scanf("%d%d",&pos,&val);if(b[pos])b[pos]=min(b[pos],val);elseb[pos]=val;}for(int i=M-2;i>=1;i--){if(!b[i])//如果当前位置为0,那么直接用最近的,大于当前位置装备的价格 b[i]=b[i+1];else if(b[i+1])//否则保留最小值 b[i]=min(b[i],b[i+1]);}int limit;for(int i=1;i<M;i++)//找到防御力的最后一个有效位置if(b[i])limit=i;for(int i=1;i<=k;i++)scanf("%d%d%d",&c[i].x,&c[i].y,&c[i].val);sort(c+1,c+1+k);build(1,1,limit);int ans=INT_MIN;int pos=1;for(int i=1;i<M;i++)//遍历攻击力(已排序)if(a[i]){while(pos<=k&&c[pos].x<i){if(c[pos].y+1<=limit)//更新防御力update(1,c[pos].y+1,limit,c[pos].val);pos++;}ans=max(ans,tree[1].mmax-a[i]);}printf("%d\n",ans);}

CodeForces - 1321E World of Darkraft: Battle for Azathoth(二维偏序+线段树)相关推荐

  1. Educational Codeforces Round 73 (Rated for Div. 2) F. Choose a Square 线段树 + 二维转一维

    传送门 文章目录 题意: 思路: 题意: 给你nnn个点(xi,yi)(x_i,y_i)(xi​,yi​),每个点有个价值cic_ici​,现在你可以框一个正方形,要求左下角和右上角的坐标(x,y)( ...

  2. Codeforces Round #620 (Div. 2) F2. Animal Observation (hard version) dp + 线段树

    传送门 文章目录 题意: 思路: 题意: 比如下面这个图: 思路: 对于这个题,比较容易就能考虑到dpdpdp,设f[i][j]f[i][j]f[i][j]为到了第iii行,覆盖了[j,j+k−1][ ...

  3. Codeforces Round #619 (Div. 2) E. Nanosoft 思维 + 二维前缀和

    传送门 文章目录 题意: 思路: 题意: 思路: 考虑到最大面积是由四种颜色构成的,且四种颜色可以从中心扩展出去,所以我们分别维护四种颜色的二维前缀和,O(1)O(1)O(1)计算矩阵内颜色的个数.现 ...

  4. Codeforces Round #345 (Div. 1) D. Zip-line 上升子序列 离线 离散化 线段树

    D. Zip-line 题目连接: http://www.codeforces.com/contest/650/problem/D Description Vasya has decided to b ...

  5. 【Codeforces Round #458 D.Bash and a Tough Math Puzzl】线段树

    链接 Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined) 题意 给你一个区间,要支持两种区间操作. 第一种操作是单点更 ...

  6. Codeforces Round #538 (Div. 2) F. Please, another Queries on Array? 线段树 + 欧拉函数

    传送门 文章目录 题意: 思路: 题意: 给你一个序列aaa,你需要实现两种操作: (1)(1)(1) 将[l,r][l,r][l,r]的aia_iai​都乘rrr. (2)(2)(2) 求ϕ(∏i= ...

  7. Codeforces Round #370 (Div. 2)E. Memory and Casinos[期望概率+线段树区间合并]详细推导

    题目链接 题目大意:就说一个赌徒在nnn个赌场里面转,在每个赌场他有pip_ipi​的胜率,如果赢了就向右走,输了就向左走,如果到达000或者n+1n+1n+1号赌场就相当退出的了赌局.定义统治区间[ ...

  8. Codeforces Round #699 (Div. 2) E.Sorting Books(贪心+DP / 线段树)超高质量题解,看不懂来打我 ~

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 E - Sorting Books 一排书架上有 nnn 本书排成一排,每本书上有一个颜色 aia_i ...

  9. CodeForces - 1295E Permutation Separation(线段树+二维偏序,好题)

    题目链接:点击查看 题目大意:给出一个1~n的排列,现在要求选择一个合适的分割点,将整个排列分为两个部分,要求通过适当的移动使得前半部分的所有数值都小于后半部分的数值,现在给出移动每个数字所花费的代价 ...

最新文章

  1. 量化网络训练--Towards Effective Low-bitwidth Convolutional Neural Networks
  2. ExtJS入门教程03,form中怎能没有validation
  3. cocos2d+lua实现帧动画播放
  4. 创建交互式shell脚本对话框
  5. dedecms后台验证码错误的解决方法
  6. 百度云服务器安装git并做远程仓库
  7. 前端小白程序员入门之前知道这些,半年后都拿到8K+的offer
  8. map/reduce之间的shuffle,partition,combiner过程的详解
  9. Note_Fast Image Processing with Fully-Convolutional Networks
  10. ASP+ACCESS校园网物品交易平台
  11. 华硕固件默认ip,新路由3 newifi d2刷机刷华硕固件教程
  12. ASP.net 2.0 中 WebResource.axd 管理资源的一些知识点
  13. 发到微信的apk文件变成apk.1,如何安装,解决办法
  14. Collectors.reducing总结
  15. 面对陌生环境,机器人如何像人一样自由穿行?
  16. 机器学习----PyTorch入门
  17. android客户端框架,最新的一版,通用Android 客户端架构设计,只有你还没看过
  18. MoverScore: Text Generation Evaluating with Contextualized Embeddings and Earth Mover Distance
  19. 前端数组json遍历3种方式总结
  20. 内存卡删除的文件如何恢复?三个步骤解决

热门文章

  1. 以下可以作为c语言合法变量名的是,2016年河南科技学院信息工程学院C语言上机编程复试笔试最后押题五套卷...
  2. Eureka-提供者与消费者
  3. Spring与日志的整合
  4. Spring程序开发
  5. AIO(Asynchronous IO)基本原理
  6. 垂直拆分后,遇到瓶颈,数据水平拆分
  7. 通过@Value + @PropertySource来给组件赋值
  8. ES6新特性之Generator函数
  9. 数据库-优化-数据库系统配置优化-配置文件优化
  10. 守护线程与非守护线程