传送门

一有「字典序最大」什么的的就懵了……这题我颓的std

首先可以发现全局最大得分很好统计,我们令它为 \(k\)

然后我们尝试构造方案,但发现无论怎么放都可能会有后效性

发现对于一个位置,可以放在这里的数有单调性

也即如果有一个比较大的数放在了这里,后面可能就匹配不够 \(k\) 个了

所以我们可以check一下, 对每个位置分两种情况

  1. 我们找一个 \(a\) 与 \(b[i]\) 形成匹配:

    那这时我们二分一个 \(a\) ,check一下去掉这个 \(a\) 后后面还能不能形成 \(k-1\) 个匹配

    如果check最后二分出的结果也不能满足,说明这个地方就不能匹配

  2. 我们找一个 \(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的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. php微信jsapi支付 支付宝支付 两码合一

    产品开会提出了这样的需求:一个二维码可以微信支付也可以支付宝支付 经过自己的钻研以及询问技术高人(本人代码一般般)和网上搜索 最终实现其功能  我用微信jsapi 和 支付宝网页支付 其实并不怎么难: ...

  2. ZYNQ 中PS端GPIO EMIO使用

    ZYNQ 中PS端GPIO EMIO使用 在使用ZYNQ进行开发设计时,往往需要对一些GPIO引脚进行配置,传统的配置方法通常在PL端进行管脚约束之后在Verilog代码中对相应引脚进行配置.这样如果 ...

  3. 「AGC029C」Lexicographic constraints

    「AGC029C」Lexicographic constraints 传送门 好像这个题非常 easy. 首先这个答案显然具有可二分性,所以问题转化为如何判定给定的 \(k\) 是否可行. 如果 \( ...

  4. 「CF505E」 Mr. Kitayuta vs. Bamboos

    「CF505E」 Mr. Kitayuta vs. Bamboos 传送门 如果没有每轮只能进行 \(k\) 次修改的限制或者没有竹子长度必须大于 \(0\) 的限制那么直接贪心就完事了. 但是很遗憾 ...

  5. UI作品评审总结:切忌过度设计,注意设计闭环

    本期,我们一起看看学长认证模块--UI同学的作品评审.   拿好小板凳,做好笔记,我们开始吧!     我们拿了两个典型的作品进行了一个讲解,做的特色都还不错,但是都有些小问题.   先来看一下第一位 ...

  6. YARN调度器(Scheduler)详解

    理想情况下,我们应用对Yarn资源的请求应该立刻得到满足,但现实情况资源往往是有限的,特别是在一个很繁忙的集群,一个应用资源的请求经常需要等待一段时间才能的到相应的资源.在Yarn中,负责给应用分配资 ...

  7. canvas实现任意正多边形的移动(点、线、面)

    前言 我在上一篇文章简单实现了在canvas中移动矩形(点线面),不清楚的小伙伴请看我这篇文章:用canvas 实现矩形的移动(点.线.面)(1). ok,废话不多说,直接进入文章主题, 上一篇文章我 ...

  8. 在Rancher中修改K8S服务参数的万金油法则

    作者简介 王海龙,Rancher中国社区技术经理,负责Rancher中国技术社区的维护和运营.拥有7年的云计算领域经验,经历了OpenStack到Kubernetes的技术变革,无论底层操作系统Lin ...

  9. 更改Nginx网站根目录以及导致的403 forbidden问题

    Nginx采用默认配置,只修改了root的网站根目录位置,再访问网站的时候提示403Forbidden的错误. 仔细检查了新文件夹的权限,也对比了心就网站根目录的权限,都是一样的. 最后尝试关闭了SE ...

  10. Fedora无法安装Qt4

    针对QT4,6安装时遇到的情况 安装平台:fedora14i686 Qt版本:4.6.2 1:解压qt的tar包 我们进行解压(tar xzvf ***.tar.gz),解压到指定目录的话后边加上: ...