JZOJ 5432. 【NOIP2017提高A组集训10.28】三元组
题目
有 \(X+Y+Z\) 个三元组 \((x[i],y[i],z[i])\),请你从每个三元组中挑数,并满足以下条件:
1、每个三元组中可以且仅可以选择一个数(即 \(x[i],y[i],z[i]\) 中的一个)
2、选择 \(x[i]\) 的三元组个数恰好为 \(X\)
3、选择 \(y[i]\) 的三元组个数恰好为 \(Y\)
4、选择 \(z[i]\) 的三元组个数恰好为 \(Z\) 问选出的数的和最大是多少
问选出的数的和最大是多少
数据规模
对于10%的数据满足,\(1<=X+Y+Z<=15\)
对于30%的数据满足,\(1<=X+Y+Z<=100\)
对于另外10%的数据满足,\(X=0\)
对于另外20%的数据满足,所有三元组中的 \(x[i]=0\)
对于另外20%的数据满足,\(1<=X+Y+Z<=100000\)
对于100%的数据满足,\(1<=X+Y+Z<=500000,0<=x[i],y[i],z[i]<=500000\)
分析
这题真妙哉!!
首先考虑 \(X = 0\) 时的贪心
显然先强制选所有 \(y[i]\)
然后按 \(z_i - y_i\) 从大到小排序,选前 \(Z\) 格就行了
然后考虑 \(X > 0\)
先强制选所有 \(x[i]\)
按 \(z_i - y_i\) 从大到小排序
枚举一个分界点
在这之前(包括本身)选 \(Z\) 个 \(z[i]\),按 \(z[i]-x[i]\) 从大到小选
在这之后选 \(Y\) 个 \(y[i]\),按 \(y[i]-x[i]\) 从大到小选
这题就可做了
当然我们显然不可能一直排序
所以我们可以用数据结构维护一下
吸口氧就过了
用桶排序即可
那我们怎样统计每次的答案呢
我们考虑每次下移临界点时,\(z\) 的选择就多了一个 \(z[i]-x[i]\),\(y\) 的选择就少了一个 \(y[i]-x[i]\)
且只会这样
那么我们用双指针挪动就行
但实现细节不是那么容易
特别是 \(z[i]-x[i]\) 或是 \(y[i]-x[i]\) 有多个的时候
就要特别讨论
所以我们还有顺便维护选取的数是桶一个单元中的第几个
\(Code\)
#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std;
const int N = 500005;
int X, Y, Z, Tz[N << 1], Ty[N << 1], Add;
struct node{int x, y, z;}a[N];
inline bool cmp(node a, node b){return (a.z - a.y) > (b.z - b.y);}
int main()
{
freopen("triple.in", "r", stdin);
freopen("triple.out", "w", stdout);
scanf("%d%d%d", &X, &Y, &Z);
LL ans = 0, sum = 0;
for(register int i = 1; i <= X + Y + Z; i++)
scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z), sum += a[i].x, Add = max(Add, max(a[i].x, max(a[i].y, a[i].z)));
sort(a + 1, a + X + Y + Z + 1, cmp);
int lz, rz, sz, ly, ry, sy;
lz = ly = Add << 1, rz = ry = 0;
for(register int i = 1; i <= Z; i++)
Tz[a[i].z - a[i].x + Add]++, lz = min(lz, a[i].z - a[i].x + Add), rz = max(rz, a[i].z - a[i].x + Add), sum += a[i].z - a[i].x;
sz = 1;
for(register int i = Z + 1; i <= X + Y + Z; i++)
Ty[a[i].y - a[i].x + Add]++, ly = min(ly, a[i].y - a[i].x + Add), ry = max(ry, a[i].y - a[i].x + Add);
for(register int i = ry, s = 0; i >= ly; i--)
if (Ty[i])
{
s += Ty[i], sum += 1LL * (i - Add) * Ty[i];
if (s >= Y){ly = i, sy = Ty[i] - (s - Y), sum -= 1LL * (i - Add) * (s - Y); break;}
}
ans = sum;
for(register int i = Z + 1; i <= X + Z; i++)
{
int del = a[i].z - a[i].x + Add;
Tz[del]++;
if (del >= lz)
{
sum += (del - Add) - (lz - Add);
if (del > rz) rz = del;
if (sz == Tz[lz])
{
++lz, sz = 1;
while (lz < rz && !Tz[lz]) ++lz;
}
else ++sz;
}
del = a[i].y - a[i].x + Add;
if (del >= ly)
{
sum -= del - Add;
if (sy >= Ty[ly])
{
--ly, sy = 1;
while (ly && !Ty[ly]) --ly;
sum += ly - Add;
}
else sum += ly - Add, ++sy;
}
Ty[del]--;
ans = max(ans, sum);
}
printf("%lld\n", ans);
}
JZOJ 5432. 【NOIP2017提高A组集训10.28】三元组的更多相关文章
- 5432. 【NOIP2017提高A组集训10.28】三元组
题目 题目大意 给你\(X+Y+Z\)个三元组\((x_i,y_i,z_i)\). 然后选\(X\)个\(x_i\),选\(Y\)个\(y_i\),选\(Z\)个\(z_i\). 每个三元组只能选择其 ...
- [JZOJ 5437] [NOIP2017提高A组集训10.31] Sequence 解题报告 (KMP)
题目链接: http://172.16.0.132/senior/#main/show/5437 题目: 题解: 发现满足上述性质并且仅当A序列的子序列的差分序列与B序列的差分序列相同 于是我们把A变 ...
- 5433. 【NOIP2017提高A组集训10.28】图
题目描述 Description 有一个n个点A+B条边的无向连通图,有一变量x,每条边的权值都是一个关于x的简单多项式,其中有A条边的权值是k+x,另外B条边的权值是k-x,如果只保留权值形如k+x ...
- 【JZOJ5428】【NOIP2017提高A组集训10.27】查询
题目 给出一个长度为n的序列a[] 给出q组询问,每组询问形如\(<x,y>\),求a序列的所有区间中,数字x的出现次数与数字y的出现次数相同的区间有多少个. 分析 我们可以维护一个前缀和 ...
- 【JZOJ5439】【NOIP2017提高A组集训10.31】Calculate
题目 分析 对于\[\sum_{i=1}^{n}\lfloor\dfrac{T-B_i}{A_i}\rfloor\] 我们考虑拆开处理,得到 \[\sum_{i=1}^{n}(\lfloor\dfra ...
- 【JZOJ5430】【NOIP2017提高A组集训10.27】图
题目 有一个n个点的无向图,给出m条边,每条边的信息形如\(<x,y,c,r>\) 给出q组询问形如\(<u,v,l,r>\) 接下来解释询问以及边的意义 询问表示,一开始你在 ...
- 【JZOJ5434】【NOIP2017提高A组集训10.30】Matrix
题目 分析 假设答案为ans, 发现\[k=\sum_{i=1}^{min(n,k)}\lfloor \dfrac{ans}{i} \rfloor\] 于是可以对ans进行二分, 用分块来求出上面的式 ...
- 【NOIP2017提高A组集训10.21】Fantasy
题目 Y sera 陷入了沉睡,幻境中它梦到一个长度为N 的序列{Ai}. 对于这个序列的每一个子串,定义其幻境值为这个子串的和,现在Y sera 希望选择K 个不同的子串并使得这K 个子串的幻境值之 ...
- JZOJ 【NOIP2017提高A组模拟9.14】捕老鼠
JZOJ [NOIP2017提高A组模拟9.14]捕老鼠 题目 Description 为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄里的仓库灭灭鼠.于是,猫被农夫约派去捕 ...
- JZOJ 【NOIP2016提高A组集训第16场11.15】SJR的直线
JZOJ [NOIP2016提高A组集训第16场11.15]SJR的直线 题目 Description Input Output Sample Input 6 0 1 0 -5 3 0 -5 -2 2 ...
随机推荐
- 包管理器pacman常用方法
详见[pacman(简体中文) - ArchWiki]:https://wiki.archlinux.org/title/Pacman_(简体中文) 更新系统: pacman -Syu 对整个系统进行 ...
- win7修改开机动画
开机动画的修改 首先win7的过场动画是存在于C:\Windows\System32\bootres.dll ,而修改过程动画就需要修改这个dll,我不会改,所以只能用工具美化大师,软媒魔方里面的一个 ...
- elasticsearch 聚合之 date_histogram 聚合
目录 1.背景 2.bucket_key如何计算 3.前置知识 4.日历和固定时间间隔 4.1 Calendar intervals 日历间隔 4.2 Fixed intervals 固定间隔 5.数 ...
- .NET周报【11月第4期 2022-11-30】
国内文章 .NET 7 的 AOT 到底能不能扛反编译? https://www.cnblogs.com/huangxincheng/p/16917197.html 在B站,公众号上发了一篇 AOT ...
- 【Shell案例】【!~//、grep反向查找、sed流编辑器】13、去掉所有包含this的句子
描述写一个 bash脚本以实现一个需求,去掉输入中含有this的语句,把不含this的语句输出示例:假设输入如下:that is your bagis this your bag?to the deg ...
- windows安装grunt时提示不是内部或外部命令解决方案
参考:https://www.cnblogs.com/hts-technology/p/8477258.html 安装windows安装elasticsearch-head时 不需要输入grunt s ...
- .NET 6 基于IDistributedCache实现Redis与MemoryCache的缓存帮助类
本文通过IDistributedCache的接口方法,实现Redis与MemoryCache统一帮助类.只需要在配置文件中简单的配置一下,就可以实现Redis与MemoryCache的切换. 目录 I ...
- 《HTTP权威指南》– 3.HTTP方法和状态码
常见HTTP方法: 常用HTTP方法 描述 是否包含主体 GET 从服务器获取一份文档 否 HEAD 只从服务器获取文档的首部 否 POST 向服务器发送需要处理的数据 是 PUT 将请求的主体部分存 ...
- PyTorch复现GoogleNet学习笔记
PyTorch复现GoogleNet学习笔记 一篇简单的学习笔记,实现五类花分类,这里只介绍复现的一些细节 如果想了解更多有关网络的细节,请去看论文<Going Deeper with Conv ...
- [sklearn] 决策树、随机森林、隐马尔可夫模型
决策树 决策树(Decision Tree)是一种用于处理分类和回归问题的无监督学习算法.如下图所示为某女青年在某相亲网站的相亲决策图.这幅图描述的都是一个非常典型的决策树模型. 通过对其相亲决策的分 ...