[NOI2019] 序列 题解
CF436E Cardboard Box的升级版。
直接上来搞六个堆的反悔贪心。
思路#
首先按照贪心的思路,将两个序列中最大
如果其中相同的小于
我们设当前序列相同的个数为
我们每一回合都要让
应该有四种情况:
-
选择一个之前选了
没选 的位置,将 选上,再丢掉一个只选了 的位置上的 。 -
选择一个之前选了
没选 的位置,将 选上,再丢掉一个只选了 的位置上的 。 -
选择一个之前选了
没选 的位置,和一个之前选了 没选 的位置,将 选上,再丢掉一个选了 的位置上的 。 -
选择一个什么都没选位置上的
,将他们选上,再选择一个之前选了 没选 的位置,和一个之前选了 没选 的位置,将 丢掉。
列成式子就是:
然后就可以开六个堆来维护这些式子。
最后,就是板子了。
Code#
#include <bits/stdc++.h>
using namespace std;
inline int read()
{
int s = 0 , f = 1; char ch;
while(!isdigit(ch = getchar())) if(ch == '-') f = -1;
while(isdigit(ch)) s = s * 10 + ch - '0' , ch = getchar();
return s * f;
}
const int maxn = 200010;
int t , n , k , l , vis[maxn] , a[maxn] , b[maxn];
struct edge
{
int id , num;
}al[maxn] , bl[maxn];
inline bool cmp(edge x , edge y)
{
return x.num > y.num;
}
struct qwq
{
int sum , id;
inline bool operator<(const qwq &tmp) const
{
return sum < tmp.sum;
}
inline bool operator>(const qwq &tmp) const
{
return sum > tmp.sum;
}
};
priority_queue<qwq , vector<qwq> , less<qwq> > q1 , q2 , q6;
priority_queue<qwq , vector<qwq> , greater<qwq> > q3 , q4 , q5;
/*
q1 -> a_i q2 -> b_i
q3 -> a_i q4 -> b_i
q5 -> a_i + b_i q6 -> a_i + b_i
*/
inline void solve(int i)
{
if(vis[i] == 0) q6.push({a[i] + b[i] , i});
if(vis[i] == 1) q2.push({b[i] , i}) , q3.push({a[i] , i});
if(vis[i] == 2) q1.push({a[i] , i}) , q4.push({b[i] , i});
if(vis[i] == 3) q5.push({a[i] + b[i] , i});
}
inline void init()
{
memset(vis , 0 , sizeof(vis));
while(q1.empty() == 0) q1.pop();
while(q2.empty() == 0) q2.pop();
while(q3.empty() == 0) q3.pop();
while(q4.empty() == 0) q4.pop();
while(q5.empty() == 0) q5.pop();
while(q6.empty() == 0) q6.pop();
}
signed main()
{
t = read();
while(t--)
{
init();
long long sum = 0 , res = 0;
//sum当前和,res当前匹配数量.
n = read() , k = read() , l = read();
for(int i = 1;i <= n;i++) a[i] = read() , al[i] = {i , a[i]};
for(int i = 1;i <= n;i++) b[i] = read() , bl[i] = {i , b[i]};
sort(al + 1 , al + n + 1 , cmp);
sort(bl + 1 , bl + n + 1 , cmp);
for(int i = 1;i <= k;i++)
sum += al[i].num , vis[al[i].id] = (vis[al[i].id] > 0 ? 3 : 1),
sum += bl[i].num , vis[bl[i].id] = (vis[bl[i].id] > 0 ? 3 : 2);
//vis_i == 1 只选 a_i
//vis_i == 2 只选 b_i
//vis_i == 3 都选了.
for(int i = 1;i <= n;i++)
res += (vis[i] == 3);
for(int i = 1;i <= n;i++) solve(i);
while(res < l)
{
long long lsum = -10000000000 , casel = 0;
while(q1.empty() == 0 && vis[q1.top().id] != 2) q1.pop();
while(q2.empty() == 0 && vis[q2.top().id] != 1) q2.pop();
while(q3.empty() == 0 && vis[q3.top().id] != 1) q3.pop();
while(q4.empty() == 0 && vis[q4.top().id] != 2) q4.pop();
while(q5.empty() == 0 && vis[q5.top().id] != 3) q5.pop();
while(q6.empty() == 0 && vis[q6.top().id] != 0) q6.pop();
if(q1.empty() == 0 && q3.empty() == 0)
{
if(lsum < q1.top().sum - q3.top().sum)
lsum = q1.top().sum - q3.top().sum , casel = 1;
}
if(q2.empty() == 0 && q4.empty() == 0)
{
if(lsum < q2.top().sum - q4.top().sum)
lsum = q2.top().sum - q4.top().sum , casel = 2;
}
if(q1.empty() == 0 && q2.empty() == 0 && q5.empty() == 0)
{
if(lsum < q1.top().sum + q2.top().sum - q5.top().sum)
lsum = q1.top().sum + q2.top().sum - q5.top().sum , casel = 3;
}
if(q3.empty() == 0 && q4.empty() == 0 && q6.empty() == 0)
{
if(lsum < q6.top().sum - q3.top().sum - q4.top().sum)
lsum = q6.top().sum - q3.top().sum - q4.top().sum , casel = 4;
}
if(casel == 1)
vis[q1.top().id] = 3 , vis[q3.top().id] = 0,
solve(q1.top().id) , solve(q3.top().id),
q1.pop() , q3.pop();
if(casel == 2)
vis[q2.top().id] = 3 , vis[q4.top().id] = 0,
solve(q2.top().id) , solve(q4.top().id),
q2.pop() , q4.pop();
if(casel == 3)
vis[q1.top().id] = 3 , vis[q2.top().id] = 3 , vis[q5.top().id] = 0,
solve(q1.top().id) , solve(q2.top().id) , solve(q5.top().id),
q1.pop() , q2.pop() , q5.pop();
if(casel == 4)
vis[q3.top().id] = 0 , vis[q4.top().id] = 0 , vis[q6.top().id] = 3,
solve(q3.top().id) , solve(q4.top().id) , solve(q6.top().id),
q3.pop() , q4.pop() , q6.pop();
sum += lsum , res++;
}
cout << sum << endl;
}
return 0;
}
作者:JiaY19
出处:https://www.cnblogs.com/JiaY19/p/15907207.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)