题目描述

  小$A$和小$B$在玩一个游戏,他们两个人每人有$n$张牌,每张牌有一个点数,并且在接下来的$n$个回合中每回合他们两人会分别打出手中的一张牌,点数严格更高的一方得一分,然而现在小$A$通过某种神秘的方法得到了小$B$的出牌顺序,现在他希望规划自己的出牌顺序使得自己在得分尽可能高的前提下出牌的字典序尽可能大。


输入格式

  第一行一个正整数$n$表示游戏进行的轮数。
  接下来一行$n$个整数,第$i$个数表示第$i$轮小$B$将要打出的牌的点数。
  接下来一行$n$个整数,表示小$A$拥有的牌的点数。


输出格式

  输出一行$n$个整数,表示小$A$出牌的顺序。


样例

样例输入:

5
1 2 3 4 5
3 2 2 1 4

样例输出:

2 3 4 2 1


数据范围与提示

  对于$20\%$的数据,$n\leqslant 10$
  对于$40\%$的数据,$n\leqslant 3,000$
  对于$60\%$的数据,$n\leqslant 6,000$
  对于$100\%$的数据,$n,a_i\leqslant 100,000$


题解

考虑贪心,一定是尽量拿小的压他更优。

这个排个序解决即可。

考虑如何另字典序最大,试着反着考虑。

发现答案满足单调性,考虑二分。

用线段树维护最大得分,然后在每一位上二分,利用贪心找到能够满足答案的最大得分即可。

时间复杂度:$\Theta(n\log n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
#define L(x) x<<1
#define R(x) x<<1|1
using namespace std;
unordered_map<int,int>mp;
int n;
int a[100001],b[100001],lc[200001],top,cnt;
int trns[400001],trsz[400001][2],trrk[400001];
void pushup(int x)
{
int res=min(trsz[L(x)][0],trsz[R(x)][1]);
trns[x]=trns[L(x)]+trns[R(x)]+res;
trsz[x][0]=trsz[L(x)][0]+trsz[R(x)][0]-res;
trsz[x][1]=trsz[L(x)][1]+trsz[R(x)][1]-res;
trrk[x]=trrk[L(x)]+trrk[R(x)];
}
void add(int x,int l,int r,int k,int id,int w)
{
if(l==r)
{
trsz[x][id]+=w;
trrk[x]+=id*w;
return;
}
int mid=(l+r)>>1;
if(k<=mid)add(L(x),l,mid,k,id,w);
else add(R(x),mid+1,r,k,id,w);
pushup(x);
}
int ask(int x,int l,int r,int k)
{
if(l==r)return l;
int mid=(l+r)>>1;
if(k<=trrk[L(x)])return ask(L(x),l,mid,k);
else return ask(R(x),mid+1,r,k-trrk[L(x)]);
}
int get(int x,int l,int r,int k)
{
if(l==r)return trrk[x];
int mid=(l+r)>>1;
if(k<=mid)return get(L(x),l,mid,k);
else return get(R(x),mid+1,r,k)+trrk[L(x)];
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){scanf("%d",&b[i]);lc[++top]=b[i];}
for(int i=1;i<=n;i++){scanf("%d",&a[i]);lc[++top]=a[i];}
sort(lc+1,lc+top+1);
for(int i=1;i<=top;i++)if(lc[i]!=lc[i-1])mp[lc[i]]=++cnt;
for(int i=1;i<=n;i++)
{
lc[mp[a[i]]]=a[i];
lc[mp[b[i]]]=b[i];
a[i]=mp[a[i]];
b[i]=mp[b[i]];
add(1,1,cnt,a[i],1,1);
add(1,1,cnt,b[i],0,1);
}
for(int i=1;i<=n;i++)
{
int res=trns[1];
int l=get(1,1,cnt,b[i])+1;
int r=trrk[1];
add(1,1,cnt,b[i],0,-1);
if(l<=r)
{
while(l<r)
{
int mid=(l+r+1)>>1;
int tmp=ask(1,1,cnt,mid);
add(1,1,cnt,tmp,1,-1);
if(trns[1]+1==res)l=mid;
else r=mid-1;
add(1,1,cnt,tmp,1,1);
}
int tmp=ask(1,1,cnt,l);
add(1,1,cnt,tmp,1,-1);
if(trns[1]+1==res)
{
printf("%d ",lc[tmp]);
continue;
}
add(1,1,cnt,tmp,1,1);
}
l=1,r=get(1,1,cnt,b[i]);
while(l<r)
{
int mid=(l+r+1)>>1;
int tmp=ask(1,1,cnt,mid);
add(1,1,cnt,tmp,1,-1);
if(trns[1]==res)l=mid;
else r=mid-1;
add(1,1,cnt,tmp,1,1);
}
int tmp=ask(1,1,cnt,l);
add(1,1,cnt,tmp,1,-1);
printf("%d ",lc[tmp]);
}
return 0;
}

rp++

[JZOJ6400]:Game(贪心+线段树+二分)的更多相关文章

  1. hdu 5338 ZZX and Permutations (贪心+线段树+二分)

    ZZX and Permutations Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/O ...

  2. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

  3. Codeforces Gym 100803G Flipping Parentheses 线段树+二分

    Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...

  4. hdu4614 线段树+二分 插花

    Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...

  5. BZOJ4391 High Card Low Card [Usaco2015 dec](贪心+线段树/set库

    正解:贪心+线段树/set库 解题报告: 算辣直接甩链接qwq 恩这题就贪心?从前往后从后往前各推一次然后找一遍哪个地方最大就欧克了,正确性很容易证明 (这里有个,很妙的想法,就是,从后往前推从前往后 ...

  6. 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块

    !!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...

  7. luogu4422 [COCI2017-2018#1] Deda[线段树二分]

    讨论帖:线段树二分的题..我还考场切过..白学 这题我一年前的模拟赛考场还切过,现在就不会了..好菜啊. 显然直接线段树拆成$\log n$个区间,然后每个区间在进行线段树二分即可. UPD:复杂度分 ...

  8. bzoj4399 魔法少女LJJ 线段树合并+线段树二分+并查集

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4399 题解 毒瘤题 \(9\) 种操作还有支持动态图的连通性 仔细读题 $ c<=7$. ...

  9. [BZOJ 2653] middle(可持久化线段树+二分答案)

    [BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...

随机推荐

  1. 刚接触SkyLine的一点小收获与感触

    因为刚接触Skyline不到一个星期,也怕把学习到的忘记掉,所以写一点学习到的一些皮毛的东西,赶紧记录一下,怕回头忘记 1.网上关于web端的开发非常多,也有很多牛人分享自己的经验,所以学习起来也相对 ...

  2. weex 通用样式以及需要注意的问题

    一.说明 weex 对于 css 样式的支持是非常有限的,并且使用样式的时候,必须遵循 weex 定义的规则. 对于不遵循 weex 样式规则的代码,往往在 web 页面上有效,而在 native 环 ...

  3. Ubuntu - 14.04下,GO语言的安装!

    一,下载GO语言的安装文件,我直接下载GO语言的安装包(64位),并不是源码: 下载地址: 64位:https://storage.googleapis.com/golang/go1.6.linux- ...

  4. Hadoop网页监控配置

    接之前的内容http://www.cnblogs.com/jourluohua/p/8734406.html 在之前那的内容中,仅实现了Hadoop的安装和运行,距离实际使用还有很远.现在先完成一个小 ...

  5. upupw : Apache Php5.5 的使用

    1. 官网下载 1. 官网下载  apache php5.5点击下载 但是 现在有时候打不开,所以提供以下方法 2. 百度云网盘下载  https://pan.baidu.com/s/1eQ2k1Su ...

  6. 爬虫框架Scrapy 的使用

    一.官网链接 https://docs.scrapy.org/en/latest/topics/architecture.html 二.Scrapy 需要安装的包 #Windows平台 # pip3 ...

  7. 19、Firewalld防火墙

    安全的考虑方向: 安全框架 OSI七层模型 硬件 机架上锁(机柜) 温度 硬件检查 网络 iptables/firewalld 仅允许公司的IP地址能连接服务器的22端口 公有云使用 安全组 系统 没 ...

  8. 2019-2020-1 20199319《Linux内核原理与分析》第五周作业

    系统调用的三层机制(上) 基础知识 1.通过库函数的方式进行系统调用,库函数用来把系统调用给封装起来. 2.CPU有四种不同的执行级别:0.1.2.3,数字越小,特权越高.Linux操作系统中采用了0 ...

  9. Linux系统吃“内存”现象

    而当我们使用free命令查看Linux系统内存使用情况时,会发现内存使用一直处于较高的水平,即使此时系统并没有运行多少软件.这正是Windows和Linux在内存管理上的区别,乍一看,Linux系统吃 ...

  10. airflow介绍

    1. airflow 介绍 1.1 airflow 是什么 Airflow is a platform to programmatically author, schedule and monitor ...