分析

GXZlegend orz

构造出一组合法的解并不是难事,但是我们需要输出的是字典序最大的解。

字典序最大有另一种理解方式,就是让越小的数尽量越靠后。

我们从树的根结点出发,从1开始填数,构造出来的一定是一组合法的解。

对于每种相同的数,可以通过线段树上二分逐个确定他们的最优位置,具体细节可以看代码。

代码

#include <bits/stdc++.h>
#define rin(i,a,b) for(register int i=(a);i<=(b);++i)
#define irin(i,a,b) for(register int i=(a);i>=(b);--i)
#define trav(i,a) for(register int i=head[a];i;i=e[i].nxt)
typedef long long LL;
using std::cin;
using std::cout;
using std::endl; inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
} const int MAXN=500005; int n,d[MAXN];
int ecnt,head[MAXN],siz[MAXN],ans[MAXN];
double k;
int sum[MAXN<<2],loc,ql,qr,kk; struct Edge{
int to,nxt;
}e[MAXN<<1]; inline void add_edge(int bg,int ed){
++ecnt;
e[ecnt].to=ed;
e[ecnt].nxt=head[bg];
head[bg]=ecnt;
} #define mid ((l+r)>>1)
#define lc (o<<1)
#define rc ((o<<1)|1) void upd(int o,int l,int r){
if(l==r){
sum[o]+=kk;
return;
}
if(loc<=mid) upd(lc,l,mid);
else upd(rc,mid+1,r);
sum[o]=sum[lc]+sum[rc];
} int query(int o,int l,int r){
if(l==r) return l;
if(sum[rc]>=kk) return query(rc,mid+1,r);
else return kk-=sum[rc],query(lc,l,mid);
} #undef mid
#undef lc
#undef rc int main(){
n=read();
scanf("%lf",&k);
rin(i,1,n) d[i]=read(),siz[i]=1;
std::sort(d+1,d+n+1);
rin(i,1,n) add_edge((int)floor(i/k),i);
irin(i,n,1) siz[(int)floor(i/k)]+=siz[i];
trav(i,0){int ver=e[i].to;loc=ver,kk=siz[ver];upd(1,1,n);}
int cnt=1;
rin(i,2,n+1){
if(d[i]==d[i-1]){#include <bits/stdc++.h>
#define rin(i,a,b) for(register int i=(a);i<=(b);++i)
#define irin(i,a,b) for(register int i=(a);i>=(b);--i)
#define trav(i,a) for(register int i=head[a];i;i=e[i].nxt)
typedef long long LL;
using std::cin;
using std::cout;
using std::endl; inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
} const int MAXN=500005; int n,d[MAXN];
int ecnt,head[MAXN],siz[MAXN],ans[MAXN];
double k;
int sum[MAXN<<2],loc,ql,qr,kk; struct Edge{
int to,nxt;
}e[MAXN<<1]; inline void add_edge(int bg,int ed){
++ecnt;
e[ecnt].to=ed;
e[ecnt].nxt=head[bg];
head[bg]=ecnt;
} #define mid ((l+r)>>1)
#define lc (o<<1)
#define rc ((o<<1)|1) void upd(int o,int l,int r){
if(l==r){
sum[o]+=kk;
return;
}
if(loc<=mid) upd(lc,l,mid);
else upd(rc,mid+1,r);
sum[o]=sum[lc]+sum[rc];
} int query(int o,int l,int r){
if(l==r) return l;
if(sum[rc]>=kk) return query(rc,mid+1,r);
else return kk-=sum[rc],query(lc,l,mid);
} #undef mid
#undef lc
#undef rc int main(){
n=read();
scanf("%lf",&k);
rin(i,1,n) d[i]=read(),siz[i]=1;
std::sort(d+1,d+n+1);
rin(i,1,n) add_edge((int)floor(i/k),i);
irin(i,n,1) siz[(int)floor(i/k)]+=siz[i];
trav(i,0){int ver=e[i].to;loc=ver,kk=siz[ver];upd(1,1,n);}
int cnt=1;
rin(i,2,n+1){
if(d[i]==d[i-1]){
++cnt;
continue;
}
irin(j,cnt,1){
kk=j;int ret=query(1,1,n);ans[ret]=d[i-1];
loc=ret,kk=-siz[ret];upd(1,1,n);
trav(l,ret){
int ver=e[l].to;
loc=ver,kk=siz[ver];upd(1,1,n);
}
}
cnt=1;
}
rin(i,1,n) printf("%d ",ans[i]);
printf("\n");
return 0;
}
++cnt;
continue;
}
irin(j,cnt,1){
kk=j;int ret=query(1,1,n);ans[ret]=d[i-1];
loc=ret,kk=-siz[ret];upd(1,1,n);
trav(l,ret){
int ver=e[l].to;
loc=ver,kk=siz[ver];upd(1,1,n);
}
}
cnt=1;
}
rin(i,1,n) printf("%d ",ans[i]);
printf("\n");
return 0;
}

[BZOJ5249][九省联考2018]IIIDX:线段树+贪心的更多相关文章

  1. [九省联考2018] IIIDX 线段树+贪心

    题目: 给出 k 和 n 个数,构造一个序列使得 d[i]>=d[i/k] ,并且字典序最大. 分析: 听说,当年省选的时候,这道题挡住了大批的高手,看上去十分简单,实际上那道弯段时间内是转不过 ...

  2. [BZOJ5249][九省联考2018]IIIDX(线段树)

    5249: [2018多省省队联测]IIIDX Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 32  Solved: 17[Submit][Statu ...

  3. BZOJ5249 九省联考2018IIIDX(线段树+贪心)

    显然这形成了一个树形结构.考虑这样一种贪心:按照曲目顺序,每次取消其父亲的预留,并选择当前可选择(保证其子树有合法选择且满足预留)的最大值,然后对其子树预留出大于等于他的一些值.这个做法显然是正确的. ...

  4. 省选九省联考T2 IIIDX(线段树)

    题目传送门:https://www.luogu.org/problemnew/show/P4364 期中考后记:期中考刚考完,感觉不咋滴,年排第3.我抗压力太差了..期末得把rank1抢回来. 本来感 ...

  5. [luogu] P4364 [九省联考2018]IIIDX(贪心)

    P4364 [九省联考2018]IIIDX 题目背景 Osu 听过没?那是Konano 最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在,他在世界知名游戏公司KONMAI ...

  6. [BZOJ 5252][LOJ 2478][九省联考2018] 林克卡特树

    [BZOJ 5252][LOJ 2478][九省联考2018] 林克卡特树 题意 给定一个 \(n\) 个点边带权的无根树, 要求切断其中恰好 \(k\) 条边再连 \(k\) 条边权为 \(0\) ...

  7. BZOJ5249:[九省联考2018]IIIDX——题解

    https://www.luogu.org/problemnew/show/P4364#sub https://www.lydsy.com/JudgeOnline/problem.php?id=524 ...

  8. 洛谷P4364 [九省联考2018]IIIDX 【线段树】

    题目 [题目背景] Osu听过没?那是Konano最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在 ,他在世界知名游戏公司KONMAI内工作,离他的梦想也越来越近了.这款 ...

  9. BZOJ.5249.[九省联考2018]iiidx(贪心 线段树)

    BZOJ LOJ 洛谷 \(d_i\)不同就不用说了,建出树来\(DFS\)一遍. 对于\(d_i\)不同的情况: Solution 1: xxy tql! 考虑如何把这些数依次填到树里. 首先对于已 ...

随机推荐

  1. # C++中对PI的引用

    #include <iostream> #include <cmath> using namespace std; int main(){ printf("%.10l ...

  2. 关于echarts中南海诸岛的显示问题

    1.china.js 文件中  echarts.registerMap('china',    //名字要是'china',不能写成'中国'   2.echarts 配置中地图名称 mapName: ...

  3. git bash中不能显示中文

    git bash中不能显示中文 问题描述:当使用git log查看提交日志时,中文字符不能正常显示问题 1.首先把git的配置改一下 git config --global core.quotepat ...

  4. Css几个兼容性问题

    1.BUG_fireFox!!!一个容器内的子容器如果要左右浮动的话,需要在这个容器设置上样式:"overflow:hidden". 注:内部元素浮动就会导致外面的容器的高度在fi ...

  5. U盘重装系统

    一.准备工作 (1)8G以上空间的U盘一个: (2)将U盘制作好启动工具: 1.下载启动工具制作软件(常用的有:大白菜.电脑店.老毛桃.快启动等等一系列软件,直接百度这些软件的名称,或者百度U盘启动制 ...

  6. H5的video标签在网页上播放MP4视频时只有声音没有画面

    最近做一个项目时,发现mp4文件播放时没有图像,只有声音,代码检查了N次,都没有问题,就算是直接使用网上的实例代码,也只能播放实例视频,mp4文件绝对路径,相对路径也都试了,还是不能播放我的mp4. ...

  7. JS通过sort(),和reverse()正序和倒序

    sort()正序   var array1 = [0,1,5,10,15]; array1.sort();//结果为:0,1,10,15,5   请注意,上面的代码没有按照数值的大小对数字进行排序,要 ...

  8. 无线传输模块HC-12

    无线传输模块HC-12使用 因为实验室的无人机需要使用一款无线传输模块进行遥控控制,我们讨论的中测试了HC-12,并对HC-12传输距离进行了简单测试.在此做下使用记录. 模块概述 HC-12 无线串 ...

  9. centos 7 私有云盘 OwnCloud 安装搭建脚本

    #!/bin/bash #Build LAMP Server Conf mysql_secure_installation service mariadb restart systemctl enab ...

  10. matplotlib:python数据处理三剑客之一

    1.基本使用 import numpy as np import matplotlib.pyplot as plt import pandas as pd # 生成一系列x x = np.linspa ...