分析

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. centos终端显示字母重叠

    在使用VMware虚拟机安装linux之后,之后调整了中文显示,但是后来不知道怎么回事在终端显示的字母很多都是重叠的. 在百度上也找到很多的解决办法 eg: 终端键入:vi /etc/fonts/co ...

  2. js获取url上的指定参数

    function getAllUrlParams(url) { // get query string from url (optional) or window var queryString = ...

  3. 如何利用 CSS 的动画原理,创作一个乒乓球对打动画

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/rvgLzK 可交互视频教 ...

  4. Windows Runtime (RT)

    学了sl for wp 开发了1年都没入门,只能说自己的学习欲望太低了. 今天偶然才发现wrt 跟 .net 是2个东西... orz. 得抛弃 sl ,wrt才是未来的主流吧... 这篇文章不错 h ...

  5. Hadoop组成架构

    Hadoop是apache用来“处理海量数据存储和海量数据分析”的分布式系统基础架构,更广义的是指hadoop生态圈.Hadoop的优势 高可靠性:hadoop底层维护多个数据副本,即使某个计算单元故 ...

  6. SpringMVC整体架构

    总结: 1. 用户发起请求到前端控制器(DispatchServlet): 2. 前端控制器没有处理业务逻辑的能力,需要找到具体的模型对象处理(Handler),到处理器映射器中查找Handler对象 ...

  7. python中format所有用法

    平时只用参数匹配,偶尔看到别人的format用法楞住没反应过来,遂记下 #通过位置 print '{0},{1}'.format('hehe',20) print '{},{}'.format('he ...

  8. C语言字符串函数总结

    原文链接 函数名: stpcpy 功 能: 拷贝一个字符串到另一个 用 法: char *stpcpy(char *destin, char *source); 程序例: #include <s ...

  9. Win10下注册APlayer组件的正确姿势

    1. 官网下载SDK 和 解码器 APlayer媒体播放引擎 2.解压SDK和解码器,把解码器codecs文件夹内所有文件复制到SDK文件夹内的bin\codecs目录里面 3.使用管理员权限打开CM ...

  10. 模拟赛小结:2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)

    比赛链接:传送门 两个半小时的时候横扫了铜.银区的所有题,签到成功混进金区.奈何后面没能开出新的题. 最后一个小时的时候xk灵机一动想出了D题的做法,讨论了一波感觉可行,赶紧去敲.结束前2分钟终于过了 ...