[JZOJ6400]:Game(贪心+线段树+二分)
题目描述
小$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(贪心+线段树+二分)的更多相关文章
- hdu 5338 ZZX and Permutations (贪心+线段树+二分)
ZZX and Permutations Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/O ...
- Codeforces Gym 100231B Intervals 线段树+二分+贪心
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...
- Codeforces Gym 100803G Flipping Parentheses 线段树+二分
Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...
- hdu4614 线段树+二分 插花
Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...
- BZOJ4391 High Card Low Card [Usaco2015 dec](贪心+线段树/set库
正解:贪心+线段树/set库 解题报告: 算辣直接甩链接qwq 恩这题就贪心?从前往后从后往前各推一次然后找一遍哪个地方最大就欧克了,正确性很容易证明 (这里有个,很妙的想法,就是,从后往前推从前往后 ...
- 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
- luogu4422 [COCI2017-2018#1] Deda[线段树二分]
讨论帖:线段树二分的题..我还考场切过..白学 这题我一年前的模拟赛考场还切过,现在就不会了..好菜啊. 显然直接线段树拆成$\log n$个区间,然后每个区间在进行线段树二分即可. UPD:复杂度分 ...
- bzoj4399 魔法少女LJJ 线段树合并+线段树二分+并查集
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4399 题解 毒瘤题 \(9\) 种操作还有支持动态图的连通性 仔细读题 $ c<=7$. ...
- [BZOJ 2653] middle(可持久化线段树+二分答案)
[BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...
随机推荐
- spark算子篇-aggregate 系列
aggregate aggregate 是比较常用的 行动 操作,不是很好懂,这里做个解释. aggregate(zeroValue, seqOp, combOp) zeroValue 是一个初始值, ...
- etcd集群安装
etcd 是一个分布式一致性k-v存储系统,可用于服务注册发现与共享配置,具有以下优点:1.简单:相比于晦涩难懂的paxos算法,etcd基于相对简单且易实现的raft算法实现一致性,并通过gRPC提 ...
- shiro登陆流程
登录请求被FormAuthenticationFilter拦截 FormAuthenticationFilter会执行其父类AdviceFilter的doFilterInternal方法 其代码如下: ...
- QQ恶搞 - 让艾特你的人语无伦次
效果图: 实现过程: 代码: 将上面的代码复制添加到你的群名片后面即可. 原理解析: 这个代码是一个Unicode控制字符 - RLO,它可以控制在它后面的所有文本都已倒序的方式显示.在qq群艾特 ...
- 四,k8s集群资源清单定义入门
目录 资源对象 创建资源的方法 清单帮助命令 创建测试清单 资源的三种创建方式 资源对象 workload:Pod, ReplicaSet, Deployment, StatefulSet, Daem ...
- Linux驱动开发之LED驱动
首先讲下字符设备控制技术 : 大部分驱动程序除了需要提供读写设备的能力外,还需要具备控制设备的能力.比如: 改变波特率. 在用户空间,使用ioctl系统调用来控制设备,原型如下:int ioctl(i ...
- 防sql注入方法
mysql_escape_string(strip_tags($arr)) /** * 函数名称:post_check() * 函数作用:对提交的编辑内容进行处理 * 参 数:$post: 要提交的内 ...
- 采用线性回归方法降低双目测距到平面的误差(sklearn)
继上篇,为了改善标定板的深度信息: remove_idx1 = np.where(Z <= 0) remove_idx2 = np.where(Z > 500)#将Z轴坐标限定在0-500 ...
- 【CF1181D】Irrigation
题目大意:给定 M 个城市,每年会选出一个城市举办比赛,现给出前 N 年城市举办比赛的情况.在接下来的年份中,每年会在举办比赛次数最小的城市举办比赛,如果有很多城市举办次数均为最小值,则在编号最小的城 ...
- k8sIngress资源
k8s提供了两种内建的云端负载均衡机制用于发布公共应用,一种是工作于传输层的service资源,它实现的是TCP负载均衡器,另一种是Ingress资源,它实现的是HTTP(S)负载均衡器. 1)TCP ...