题解 Game
一有「字典序最大」什么的的就懵了……这题我颓的std
首先可以发现全局最大得分很好统计,我们令它为 \(k\)
然后我们尝试构造方案,但发现无论怎么放都可能会有后效性
发现对于一个位置,可以放在这里的数有单调性
也即如果有一个比较大的数放在了这里,后面可能就匹配不够 \(k\) 个了
所以我们可以check一下, 对每个位置分两种情况
我们找一个 \(a\) 与 \(b[i]\) 形成匹配:
那这时我们二分一个 \(a\) ,check一下去掉这个 \(a\) 后后面还能不能形成 \(k-1\) 个匹配
如果check最后二分出的结果也不能满足,说明这个地方就不能匹配我们找一个 \(a\) ,但它无法与 \(b[i]\) 形成匹配:
二分一个最大的 \(a\) ,且删掉这个 \(a\) 后后面仍能形成 \(k\) 个匹配
然后就是如何check了……可以 \(O(n)\) 跑check
神仙思路:开一棵权值线段树,分别维护这段值域中剩余未匹配a, b的个数及匹配的数量
因为右区间的a一定可以匹配左区间的b,所以这个东西可以合并
然后就每次单点修改删掉一个数,看根节点的匹配个数就行了
- 处理「字典序最大/小的合法方案」(?):如果每个位置的取值有单调性,二分找这里能放的,且这里放了后面仍能满足要求的最大的取值。其实这样的话难点在于check
Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
//#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n;
int a[N], b[N];
namespace force{
int ans[N], maxn;
void solve() {
sort(a+1, a+n+1);
do {
int cnt=0;
for (int i=1; i<=n; ++i) if (a[i]>b[i]) ++cnt;
if (cnt>=maxn) memcpy(ans+1, a+1, sizeof(int)*n), maxn=cnt;
} while (next_permutation(a+1, a+n+1));
for (int i=1; i<=n; ++i) printf("%d ", ans[i]);
printf("\n");
exit(0);
}
}
namespace task1{
int a2[N], b2[N], ans[N];
int cnt[N];
inline bool cmp(int a, int b) {return a>b;}
bool check(int k) {
int pos=1;
for (int i=1; i<=k; ++i) {
for (; pos<=n; ++pos) {
if (a2[i]>b2[pos]) {
++pos;
goto jump;
}
}
if (pos>n) return 0;
jump: ;
}
return 1;
}
void solve() {
for (int i=1; i<=n; ++i) ++cnt[a[i]];
memcpy(a2, a, sizeof(a));
memcpy(b2, b, sizeof(b));
sort(a2+1, a2+n+1, cmp); sort(b2+1, b2+n+1, cmp);
int l=0, r=n, mid;
while (l<=r) {
mid=(l+r)>>1;
if (check(mid)) l=mid+1;
else r=mid-1;
}
mid=l-1;
//cout<<"mid: "<<mid<<endl;
for (int i=1; i<=mid; ++i) --cnt[a2[i]];
int pos=1;
for (int i=1; i<=mid; ++i) {
for (; pos<=n; ++pos) {
if (a2[i]>b2[pos]) {
ans[pos]=a2[i];
++pos;
goto jump2;
}
}
jump2: ;
}
pos=1;
for (int i=N; ~i; --i)
while (cnt[i]) {
while (ans[pos]) ++pos;
ans[pos]=i;
--cnt[i];
}
for (int i=1; i<=n; ++i) printf("%d ", ans[i]);
printf("\n");
exit(0);
}
}
namespace task{
multiset<int> s;
int tl[N<<2], tr[N<<2], sa[N<<2], sb[N<<2], sum[N<<2], k;
#define tl(p) tl[p]
#define tr(p) tr[p]
#define sa(p) sa[p]
#define sb(p) sb[p]
#define sum(p) sum[p]
void pushup(int p) {
//cout<<"pushup "<<p<<' '<<tl(p)<<' '<<tr(p)<<endl;
//cout<<"sa: "<<sa(p<<1)<<' '<<sa(p<<1|1)<<endl;
//cout<<"sb: "<<sb(p<<1)<<' '<<sb(p<<1|1)<<endl;
int dlt=min(sb(p<<1), sa(p<<1|1));
sum(p)=sum(p<<1)+sum(p<<1|1)+dlt;
sa(p)=sa(p<<1)+sa(p<<1|1)-dlt;
sb(p)=sb(p<<1)+sb(p<<1|1)-dlt;
}
void build(int p, int l, int r) {
tl(p)=l; tr(p)=r;
if (l==r) return ;
int mid=(l+r)>>1;
build(p<<1, l, mid);
build(p<<1|1, mid+1, r);
}
void upd(int p, int pos, int dat, int typ) {
if (tl(p)==tr(p)) {(typ?sa:sb)[p]+=dat; return ;}
int mid=(tl(p)+tr(p))>>1;
if (pos<=mid) upd(p<<1, pos, dat, typ);
else upd(p<<1|1, pos, dat, typ);
pushup(p);
}
void query(int p) {
cout<<"query "<<p<<' '<<tl(p)<<' '<<tr(p)<<' '<<sa(p)<<' '<<sb(p)<<' '<<sum(p)<<endl;
if (tl(p)==tr(p)) return ;
query(p<<1); query(p<<1|1);
}
void solve() {
build(1, 1, N);
for (int i=1; i<=n; ++i) upd(1, a[i], 1, 1), s.insert(a[i]);
for (int i=1; i<=n; ++i) upd(1, b[i], 1, 0);
k=sum(1);
//query(1);
//cout<<"k: "<<k<<endl;
for (int i=1,l,r,mid,rb; i<=n; ++i) {
upd(1, b[i], -1, 0);
l=b[i]+1, r=rb=*s.rbegin();
//cout<<"lr: "<<l<<' '<<r<<endl;
while (l<=r) {
mid=(l+r)>>1;
upd(1, mid, -1, 1);
if (sum(1)==k-1) l=mid+1;
else r=mid-1;
upd(1, mid, 1, 1);
}
if (b[i]+1<=rb) upd(1, l-1, -1, 1);
if (b[i]+1<=rb && sum(1)==k-1) {--k; printf("%d ", l-1); s.erase(s.find(l-1));}
else {
if (b[i]+1<=rb) upd(1, l-1, 1, 1);
l=1, r=b[i];
while (l<=r) {
mid=(l+r)>>1;
upd(1, mid, -1, 1);
if (sum(1)==k) l=mid+1;
else r=mid-1;
upd(1, mid, 1, 1);
}
upd(1, l-1, -1, 1);
printf("%d ", l-1);
//if (s.find(l-1)==s.end()) cout<<"error2"<<endl;
s.erase(s.find(l-1));
}
}
printf("\n");
exit(0);
}
}
signed main()
{
n=read();
for (int i=1; i<=n; ++i) b[i]=read();
for (int i=1; i<=n; ++i) a[i]=read();
//force::solve();
//task1::solve();
task::solve();
return 0;
}
题解 Game的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
- JSOI2016R3 瞎BB题解
题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...
随机推荐
- yoyogo v1.7.5 发布, 独立依赖注入DI
YoyoGo v1.7.5 YoyoGo (Go语言框架) 一个简单.轻量.快速.基于依赖注入的微服务框架( web .grpc ),支持Nacos/Consoul/Etcd/Eureka/k8s / ...
- 解决 .net core 中 nuget 包版本冲突问题[转载]
今天在一个 asp.net core 项目中遇到了 nuget 包版本冲突的问题,错误信息如下: Version conflict detected for Microsoft.AspNet.WebA ...
- 【重学Java】多线程进阶(线程池、原子性、并发工具类)
线程池 线程状态介绍 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态.线程对象在不同的时期有不同的状态.那么Java中的线程存在哪几种状态呢?Java中的线程 状态被定 ...
- IP地址详解
讲之前了解一些网络设备的作用: 交换机:组建局域网 路由器:连接内外网 网关:一个网络的出口(Gate Way = GW)一般网关在路由器上 局域网(也称内网) 一个简单的局域网的基本组成设备:交换机 ...
- 1.前言-聊聊Java这条路
一.解决大家的疑问 1.零基础学习编程? 有编程基础的比零基础的困难,毕竟有一些固定思维 目标:爱好.做网站.做游戏 2.英语不好能学吗? 程序并没有大家想象的那么多英语,天天都在用,慢慢就掌握了 3 ...
- VMware workstation虚拟机配置文件不兼容无法使用解决方法
VMware workstation虚拟机配置文件不兼容无法使用解决方法打开VMware workstation虚拟机提示:配置文件"--.vmx"是由Vmware产品创建,但该产 ...
- Hive——基本DML语句
Hive--基本DML语句 DML:Data Manipulation Language(数据操作语言,与关系型数据库相似) 官方手册:https://cwiki.apache.org/conflue ...
- Leetcode:559. N叉树的最大深度
Leetcode:559. N叉树的最大深度 Leetcode:559. N叉树的最大深度 Talk is cheap . Show me the code . /* // Definition fo ...
- 数据库-SQL 语法
数据库-SQL 语法 二十余年如一梦,此身虽在堪惊. 简介:数据库-SQL 语法 一.基础 模式定义了数据如何存储.存储什么样的数据以及数据如何分解等信息,数据库和表都有模式. 主键的值不允许修改,也 ...
- PC免费的小说阅读器,可提取章节
最近自己做了个小说阅读器,就是下面这个东西啦,目前仅支持Window系统: 个人喜欢在电脑.平板上等大屏幕设备上阅读小说或电子书籍.原因其一是屏幕足够大,可以选择更舒服的字体大小:其二是觉得小屏幕看字 ...