题目描述

  小$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. HTML5自学2

    1.1   文字格式 一个杂乱无序.堆砌而成的网页,会让人感觉枯无味,而一个美观大方的网页,会让人有美轮美奂,流连忘返的感觉,本节将介绍如何设置网页文本格式. 文字格式包括字体.字号.文字颜色.字体风 ...

  2. xargs、chattr命令

    一.xargs:将标准输入转化成命令行参数 用法:xargs [OPTION] ... COMMAND INITIAL-ARGS ...使用参数INITIAL-ARGS运行COMMAND,并从输入中读 ...

  3. Sentinel基本使用--基于QPS流量控制(二), 采用Warm Up预热/冷启动方式控制突增流量

    Sentinel基本使用--基于QPS流量控制(二), 采用Warm Up预热/冷启动方式控制突增流量 2019年02月18日 23:52:37 xiongxianze 阅读数 398更多 分类专栏: ...

  4. mongoose操作笔记

    一.mongoose文档地址: https://cn.mongoosedoc.top/docs/api.html#update_update https://www.cnblogs.com/web-f ...

  5. button标签与input type=button标签使用的差异

    button标签和input type=button标签都是html文档中用来表示按钮属性的元素,不过他们在布局和实际使用功能中存在一些差异. 下面将项目中遇到的一些总结如下: 1.属性和布局差异. ...

  6. 网速监控-nload

    用来监控系统网卡实时网速的. 安装 yum install nload -y # 或 apt install nload -y 使用 # 直接运行默认监控第一个网卡, 使用上下方向键来切换网卡. nl ...

  7. Centos7:mysql5.6安装,配置及使用(RPM方式)

    1.首先安装好jdk环境,本机所用环境为jdk1.8 2.卸载MariaDB(Centos7自带)与Mysql 2.1卸载:MariaDB #rpm -qa | grep -i mariadb //查 ...

  8. colaui基础

    监控 c-watch // 监控的方法函数 on 监控的参数名字 div(c-watch="fun on style" c-bind="styles") // ...

  9. js 数据类型的判断

    1. typeof 运算符 typeof 可以判断基本数据类型: typeof 123; // "number" typeof 'abc'; // "string&quo ...

  10. TensorFlow入门——MNIST深入

    #load MNIST data import tensorflow.examples.tutorials.mnist.input_data as input_data mnist = input_d ...