LOJ 3158: 「NOI2019」序列
题目传送门:LOJ #3158。
题意简述:
给定两个长度为 \(n\) 的正整数序列 \(a,b\),要求在每个序列中都选中 \(K\) 个下标,并且要保证同时在两个序列中都被选中的下标至少有 \(L\) 个,使得选中的下标对应的数的总和最大。
题解:
题目相当于要求在两个序列中选出 \(K\) 对数,不妨一对一对地选。
有个结论是说,上一步的最优决策一定不会再反悔,就是已经选的不会再撤销。
然后做完了,用堆维护一些东西,精细实现就好了。
下面是代码,复杂度 \(\mathcal{O}\left(\sum n\log n\right)\)。
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cctype>
#define fi first
#define se second
#define mp std::make_pair
typedef long long LL;
typedef std::pair<int, int> pii;
typedef std::priority_queue<pii> PQ;
const int MN = 200005;
inline void read(int &x) {
x = 0; static char ch;
while (!isdigit(ch = getchar())) ;
while (x = x * 10 + (ch & 15), isdigit(ch = getchar()));
}
inline void write(LL x) {
static char st[15];
static char *t = st;
while (x) *t++ = (x % 10) | 48, x /= 10;
while (t != st) putchar(*--t);
putchar('\n');
}
int N, K, L;
int A[MN], B[MN];
bool vA[MN], vB[MN];
PQ A0, B0, A1, B1, C;
LL Ans;
int main() {
freopen("sequence.in", "r", stdin);
freopen("sequence.out", "w", stdout);
int T; scanf("%d", &T);
while (T--) {
Ans = 0;
while (!A0.empty()) A0.pop();
while (!B0.empty()) B0.pop();
while (!A1.empty()) A1.pop();
while (!B1.empty()) B1.pop();
while (!C.empty()) C.pop();
read(N), read(K), read(L);
for (int i = 1; i <= N; ++i) read(A[i]);
for (int i = 1; i <= N; ++i) read(B[i]);
for (int i = 1; i <= N; ++i) {
vA[i] = vB[i] = 0;
A0.push(mp(A[i], i));
B0.push(mp(B[i], i));
C.push(mp(A[i] + B[i], i));
}
int left = K - L;
for (int cnt = 1; cnt <= K; ++cnt) {
while (vA[A0.top().se]) A0.pop();
while (vB[B0.top().se]) B0.pop();
if (left) {
pii a = A0.top(), b = B0.top();
A0.pop(), B0.pop();
Ans += a.fi + b.fi;
int ap = a.se, bp = b.se;
vA[ap] = vB[bp] = 1;
if (ap == bp) C.pop();
else {
--left;
if (vB[ap]) ++left, A1.pop();
else B1.push(mp(B[ap], ap));
if (vA[bp]) ++left, B1.pop();
else A1.push(mp(A[bp], bp));
}
}
else {
pii c0 = C.empty() ? mp(0, 0) : C.top();
while (vA[c0.se] || vB[c0.se])
C.pop(), c0 = C.empty() ? mp(0, 0) : C.top();
pii a0 = A0.top(), b0 = B0.top();
pii a1 = A1.empty() ? mp(-b0.fi, 0) : A1.top();
pii b1 = B1.empty() ? mp(-a0.fi, 0) : B1.top();
int a = a1.fi + b0.fi;
int b = b1.fi + a0.fi;
if (c0.fi >= a && c0.fi >= b)
Ans += c0.fi, vA[c0.se] = vB[c0.se] = 1;
else if (a >= b) {
Ans += a;
A1.pop(), B0.pop(), vA[a1.se] = vB[b0.se] = 1;
if (b1.se == b0.se) B1.pop(), ++left;
else A1.push(mp(A[b0.se], b0.se));
}
else {
Ans += b;
B1.pop(), A0.pop(), vB[b1.se] = vA[a0.se] = 1;
if (a1.se == a0.se) A1.pop(), ++left;
else B1.push(mp(B[a0.se], a0.se));
}
}
} write(Ans);
}
return 0;
}
证明?不要问我证明啊!其实仔细分析一下应该是能证出来的,再不行就先套个费用流模型。
LOJ 3158: 「NOI2019」序列的更多相关文章
- Loj #3059. 「HNOI2019」序列
Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...
- loj #2051. 「HNOI2016」序列
#2051. 「HNOI2016」序列 题目描述 给定长度为 n nn 的序列:a1,a2,⋯,an a_1, a_2, \cdots , a_na1,a2,⋯,an,记为 a[1: ...
- LOJ 3160: 「NOI2019」斗主地
题目传送门:LOJ #3160. 简要题意: 有一个长度为 \(n\) 的序列 \(a\),初始时 \(a_i=i\) 或 \(a_i=i^2\),这取决于 \(\mathrm{type}\) 的值. ...
- LOJ #2183「SDOI2015」序列统计
有好多好玩的知识点 LOJ 题意:在集合中选$ n$个元素(可重复选)使得乘积模$ m$为$ x$,求方案数对$ 1004535809$取模 $ n<=10^9,m<=8000且是质数,集 ...
- LOJ 3059 「HNOI2019」序列——贪心与前后缀的思路+线段树上二分
题目:https://loj.ac/problem/3059 一段 A 选一个 B 的话, B 是这段 A 的平均值.因为 \( \sum (A_i-B)^2 = \sum A_i^2 - 2*B \ ...
- LOJ 3159: 「NOI2019」弹跳
题目传送门:LOJ #3159. 题意简述: 二维平面上有 \(n\) 个整点,给定每个整点的坐标 \((x_i,y_i)\). 有 \(m\) 种边,第 \(i\) 种边从 \(p_i\) 号点连向 ...
- LOJ 3156: 「NOI2019」回家路线
题目传送门:LOJ #3156. 题意简述: 有一张 \(n\) 个点 \(m\) 条边的有向图,边有两个权值 \(p_i\) 和 \(q_i\)(\(p_i<q_i\))表示若 \(p_i\) ...
- 「NOI2019」序列
NKOJ卡常卡不过QAQ description 给两个A,B序列,让你分别在A,B中各选k个数,其中至少有L对下标相等. Solution 把问题转化为至多选n-K对下标不同的对. 配对问题就用费用 ...
- loj#2002. 「SDOI2017」序列计数(dp 矩阵乘法)
题意 题目链接 Sol 质数的限制并没有什么卵用,直接容斥一下:答案 = 忽略质数总的方案 - 没有质数的方案 那么直接dp,设\(f[i][j]\)表示到第i个位置,当前和为j的方案数 \(f[i ...
随机推荐
- 洛谷 P4290 [HAOI2008]玩具取名
传送门 思路 博客半年没更新了,来更新个博文吧 在\(dsr\)聚聚博客的帮助下,我用半个上午和一个中午的时间苟延残喘地完成了这道题 先是读题目读大半天,最后连个样例都看不懂 之后又是想思路,实在想不 ...
- [LeetCode] 241. Different Ways to Add Parentheses 添加括号的不同方式
Given a string of numbers and operators, return all possible results from computing all the differen ...
- CSP-S考前救急(考试前还是别复习了,事实证明复习了也没考到...
“不要为明天而忧虑,因为明天自有明天的忧虑:一天的难处一天当就够了.” 念念不忘,必有回响. 考试结束前15分钟停止写代码.然后按照以下顺序进行检查: -检查文件名是否写错-检查是否打开文件输入输出 ...
- 认识map-reduce
基本概念 map-reduce1.0 例子: hadoop streaming 用语言驱动map-reduce的话,使用的hadoop streaming命令,可以通过python,php,java来 ...
- C#原型模式(深拷贝、浅拷贝)
原型模式就是用于创建重复的对象,当想要创建一个新的对象但是开销比较大或者想将对象的当前状态保存下来的时候,我们就可以使用原型模式. 创建原型 public abstract class Base { ...
- 刷完欧拉计划中难度系数为5%的所有63道题,我学会了Rust中的哪些知识点?
我为什么学Rust? 2019年6月18日,Facebook发布了数字货币Libra的技术白皮书,我也第一时间体验了一下它的智能合约编程语言MOVE,发现这个MOVE是用Rust编写的,看来想准确理解 ...
- sync 异步编程
using System; using System.Net; using System.Threading; using System.Threading.Tasks; namespace Cons ...
- 1+x证书《Web前端开发》等级考试样题
Web前端开发初级理论考试样题2019 http://blog.zh66.club/index.php/archives/149/ Web前端开发初级实操考试样题2019 http://blog.zh ...
- SpringBoot系列之profles配置多环境(篇一)
SpringBoot profles配置多环境 23/100 发布文章 u014427391 软件环境简介 这里介绍一下SpringBoot提供的profiles属性加上maven配置一下多环境,在实 ...
- springmvc和mybatis面试题(含答案)
Spring MVC Framework有这样一些特点: 1.它是基于组件技术的.全部的应用对象,无论控制器和视图,还是业务对象之类的都是java组件.并且和Spring提供的其他基础结构紧密集成. ...