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 ...
随机推荐
- 第2-4-6章 springboot整合规则引擎Drools-业务规则管理系统-组件化-中台
目录 7. Spring整合Drools 7.1 Spring简单整合Drools 7.1.1 以上代码均在drools_spring项目中 7.2 Spring整合Drools+web 7.2 以上 ...
- ArcObjects SDK开发 004 如何学习好ArcObjects SDK开发
1.基于Arcobjects SDK可以做什么 基于Arcobjects SDK开发,大部分情况下就是做桌面GIS应用程序.AO写的代码是不能直接在Web服务上运行的,但如果你前端是JS,需要后端处理 ...
- .NET 6使用ImageSharp给图片添加水印
.NET 6 中,使用System.Drawing操作图片,生成解决方案或打包的时候,会有警告,意思是System.Drawing仅在 'windows' 上受支持.微软官方的解释是: Syste ...
- day25 前端
https://www.dcloud.io/hbuilderx.html 下载HbuilderX,直接解压缩双击打开 html5 <!DOCTYPE html><!-- 文档类型,声 ...
- mysql基础问题三问(底层逻辑;正在执行;日志观察)
背景:经常面试会遇到且实际工作中也会应用到的三个场景: 目录: 一.mysql查询时的底层原理是什么? 二.如何查看正在执行的mysql语句? 三.如何观察mysql运行过程中的日志信息? - - - ...
- <五>function的实现原理
类模版std::function是一种通用.多态的函数封装.std::function的实例可以对任何可以调用的目标实体进行存储.复制.和调用操作,这些目标实体包括普通函数.Lambda表达式.函数指 ...
- 前端入门 HTTP协议 HTML简介 head内常见标签 body内常见标签 特殊符号 列表标签 表格标签 表单标签
目录 前端和后端的概念 前端前戏之B/S架构 数据交互的协议 HTTP协议 1.四大特性 1. 基于请求响应 2. 基于TCP.IP作用与应用层之上的协议 3. 无状态 4. 无\短连接 2.数据格式 ...
- echarts去除下载小图标
toolbox: { show: true, orient: 'vertical', left: 'right', top: 'center', feature: { dataView: { read ...
- Python免杀过360
本文章仅供参考学习 作者:mantou 博客地址:https://www.cnblogs.com/mantou0/ 分离免杀 这个我就不多说了,效果确实不错,网上关于分离免杀的也有很多文章 不分离过3 ...
- go_xml_learn
结构体转换为xml: type Person struct { XMLName xml.Name `xml:"person"` Name string `xml:"nam ...