博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
51Nod1364 最大字典序排列
阅读量:5140 次
发布时间:2019-06-13

本文共 1539 字,大约阅读时间需要 5 分钟。

一道比较简单的贪心题

容易想到从前到后确定每一位

我们可以用一个splay来维护当前未确定的部分的顺序

假设当前剩下k次操作机会

那么我们可以求出splay中前k+1个元素中的最大元素i,令k减少rank(i),让后将其输出并从splay中删掉

最后k=0时,输出splay中剩余元素

比题解那个线段树好写多了,主要是不用想,而且splay还挺快的

#include
#include
#include
#define N 100010#define son(x) (s[f[x]][1]==x)using namespace std;int f[N],s[N][2],sz[N],l[N],t[N];int n,k,cnt=0,rt=0;inline int ps(int x){
sz[x]=sz[s[x][0]]+sz[s[x][1]]+1; t[x]=max(l[x],max(t[s[x][0]],t[s[x][1]]));}inline void rot(int x){
int p=f[x],g=f[p],d=son(x); s[p][d]=s[x][!d]; f[s[p][d]]=p; s[x][!d]=p; f[p]=x; f[x]=g; if(g) s[g][p==s[g][1]]=x; ps(p); ps(x);}inline void splay(int x,int r=0){
for(int p;(p=f[x])!=r;rot(x)) if(f[p]!=r && son(x)==son(p)) rot(p); if(!r) rt=x;}inline int select(int k,int x=rt){
for(int w;;){
w=sz[s[x][0]]+1; if(w==k) return x; if(k
t[s[x][1]]) x=s[x][0]; else x=s[x][1]; }}int main(){
scanf("%d%d",&n,&k); for(int x,i=1;i<=n;++i){
scanf("%d",l+i); if(i>1){
f[i-1]=i; s[i][0]=i-1; ps(i); } else sz[i]=1,ps(i); } rt=n; for(int i=1,j;k>0&&i<=n;++i){
splay(select(min(k+1,sz[rt]))); if(l[rt]>t[s[rt][0]]) j=rt; else splay(fMax(s[rt][0])); printf("%d\n",l[rt]); k-=sz[s[rt][0]]; rt=merge(s[rt][0],s[rt][1]); f[rt]=0; } while(sz[rt]) splay(select(1)),printf("%d\n",l[rt]),rt=merge(s[rt][0],s[rt][1]),f[rt]=0;;}

转载于:https://www.cnblogs.com/Extended-Ash/p/9477087.html

你可能感兴趣的文章
Hadoop分布式文件系统中架构和设计要点汇总
查看>>
cout和printf
查看>>
UVa 10088 - Trees on My Island (pick定理)
查看>>
#C++PrimerPlus# Chapter11_Exersice4_mytimeV4
查看>>
iOS8 针对开发者所拥有的新特性汇总如下
查看>>
Jmeter + Grafana搭建实时监控可视化
查看>>
uCGUI字符串显示过程分析和uCGUI字库的组建
查看>>
h5唤起app
查看>>
SQL Server 2008 /SQL Server 2008 R2 配置数据库邮件
查看>>
[转]vs2010编译金山代码
查看>>
数学图形之Boy surface
查看>>
处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“Manag
查看>>
3.浏览器检测
查看>>
01: socket模块
查看>>
Border-radius
查看>>
mysql触发器
查看>>
Redis学习笔记(1)Redis安装和启动
查看>>
淌淌淌
查看>>
BZOJ1002:[FJOI2007]轮状病毒
查看>>
SSD5_Recommended Exercise 4 分析
查看>>