2018 省选 D1T2 IIIDX
题目大意:
给出k、n个数选择一种字典序最大的排列,使得对于任意的i,di>=d[i/k](下取整 下同)
分析:
很容易想到的是建树,将i的父亲设为[i/k],之后建有向边。
60分贪心:
将原先的a数组升序排列,直接根据子树大小分配排位。pai[i]=(同层级剩余的)-(子树大小)+1; 然而对于di有相同的情况时,也许可能会使得子树之间值发生交换,仍使得命题成立。
例如: [1,2,2,3] k=2;
正解:[1,2,3,2]
贪心: [1,2,2,3]
问题在于,因为题目中说了满足单调不降即可,而贪心则极力向后取数,可能会将大的数预留给自己较大编号的后代。如这个例子中,2号取到了3号排位,将4号排位、最大的3留给了4号。而3号就只剩下了2号排位。
我们想最大化较小的编号的值,就让它尽量往后取排位。 但是由于单调不降,可以让2号取2号位,4号取3号位,3号取4号位。使得答案更优。
正解:
线段树。
令原数组a降序排列。 令f[i]表示i号排位左边还有几个位置上的数是可以取到的。线段树维护这个区间内f的最小值。
显然这个f数组单调不降。对于从小到大的第i个编号,我们每次二分一个x,使得找到一个最靠左的位置,使得f[x]>=size[i],若有多个x,找到最靠右的一个x(这样使得在x取值最优时,尽可能将大的数留给后面的数。)让[x~n]区间上的值都减去size[i]
具体实现:
1.先判断到了i号点时,有没有进入下一个层级,如果有,将上一个层级预留的值都加回来(+size[fa]-1),才能二分、利用。
2.二分找到一个p;将p移动到同一个数值的、未用过的最右边。
3.将p赋值给ans[i],记录该p已经被用过(详见代码中nxt[p]++,这样保证下次减回来能多减一个位置)
4.给子树预留位置。
详见代码:
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=+;
int nxt[N],a[N],ans[N],fa[N],size[N];
int n;
double k;
struct node{
int mi,l,r;
int add;
#define mix t[x].mi
#define lx t[x].l
#define rx t[x].r
#define lsx x<<1
#define rsx x<<1|1
#define ax t[x].add
#define milsx t[lsx].mi
#define mirsx t[rsx].mi
#define alsx t[x<<1].add
#define arsx t[x<<1|1].add
}t[N<<];
void push(int x)
{
if(!ax) return;
milsx+=ax;
mirsx+=ax;
alsx+=ax;
arsx+=ax;
ax=;
}
void build(int l,int r,int x)
{
if(l==r)
{
mix=l,lx=l,rx=r;ax=;return;
}
int mid=(l+r)>>;
lx=l,rx=r,ax=;
build(l,mid,lsx);
build(mid+,r,rsx);
mix=min(mirsx,milsx);
}
void add(int l,int r,int x,int c)
{
if(l<=lx&&rx<=r)
{
mix+=c;
ax+=c;return;
}
push(x);
int mid=(lx+rx)>>;
if(l<=mid) add(l,r,lsx,c);
if(mid<r) add(l,r,rsx,c);
mix=min(milsx,mirsx);
}
int find(int x,int d)
{
if(lx==rx) return lx+(mix<d);
push(x);
if(mirsx<d) return find(rsx,d);
return find(lsx,d);
}
bool cmp(int a,int b) {return a>b;}
void prework()
{
sort(a+,a+n+,cmp);
for(int i=;i<=n;i++)
fa[i]=int(i/k),size[i]=;
for(int i=n-;i;i--)
if(a[i]==a[i+]) nxt[i]=nxt[i+]+;
for(int i=n;i;i--)
size[fa[i]]+=size[i]; }
int main()
{
scanf("%d%lf",&n,&k);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
prework();
int root=;
build(,n,root);
for(int i=;i<=n;i++)
{
if(fa[i]!=fa[i-]) add(ans[fa[i]],n,root,size[fa[i]]-);
int p=find(root,size[i]);
p+=nxt[p];nxt[p]++;p-=nxt[p]-;ans[i]=p;
add(p,n,root,-size[i]);
}
for(int i=;i<=n;i++)
printf("%d ",a[ans[i]]);
return ;
}
2018 省选 D1T2 IIIDX的更多相关文章
- 2018 省选 T1 一双木棋
题目描述 菲菲和牛牛在一块n 行m 列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束. 落子的规则是:一个格子可以落子当且仅当 ...
- [游记] Noip 2018
飞雪连天射白鹿, 笑书神侠倚碧鸳 $ 2018/12/14 $ 经历了 \(noip\) 玩完的心态爆炸之后,还是决定稍微写一下游记记录一下\(QAQ\),以免以后就忘了. 然后打算先写个框架之后再慢 ...
- 【科技】KD-tree随想
大概就是个复杂度对的暴力做法,在你不想写二维线段树等的时候优秀的替代品. 优点:思路简单,代码好写. 他大概有两种用法(虽然差不多). 在平面坐标系中干一些事情: 例如最常规的平面最近最远点,不管是欧 ...
- 一双木棋(chess)
一双木棋(chess) 题目描述 菲菲和牛牛在一块 nn 行 mm 列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束.落子的规 ...
- 「九省联考 2018」IIIDX 解题报告
「九省联考 2018」IIIDX 这什么鬼题,送的55分要拿稳,实测有60? 考虑把数值从大到小摆好,每个位置\(i\)维护一个\(f_i\),表示\(i\)左边比它大的(包括自己)还有几个数可以选 ...
- 5249: [2018多省省队联测]IIIDX
5249: [2018多省省队联测]IIIDX 链接 分析: 贪心. 将给定的权值从大到小排序,从第一个往后挨个赋值,考虑第i个位置可以赋值那些树.首先满足前面必须至少有siz[i]个权值没选,如果存 ...
- bzoj 5249 [2018多省省队联测] IIIDX
bzoj 5249 [2018多省省队联测] IIIDX Link Solution 首先想到贪心,直接按照从大到小的顺序在后序遍历上一个个填 但是这样会有大问题,就是有相同的数的时候,会使答案不优 ...
- [luogu] P4364 [九省联考2018]IIIDX(贪心)
P4364 [九省联考2018]IIIDX 题目背景 Osu 听过没?那是Konano 最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在,他在世界知名游戏公司KONMAI ...
- [九省联考2018]IIIDX
题目描述 这一天,Konano接到了一个任务,他需要给正在制作中的游戏<IIIDX>安排曲目的解锁顺序.游戏内共有n首曲目 ,每首曲目都会有一个难度d,游戏内第i首曲目会在玩家Pass第t ...
随机推荐
- PHP生成QRCode二维码
php生成QRCode二维码示例 <?php //引入 phpqrcode 类库 //phpqrcode下载地址:https://github.com/t0k4rt/phpqrcode //或从 ...
- Jmeter(三十四)_Beanshell解析并提取json响应
1:前置条件 将fastjson-1.2.49.jar包置于jmeter的lib目录下,并将该jar包添加到测试计划的Library中:否则会报:Typed variable declaration ...
- Linux umask
新建一个文件或目录,它的默认权限是什么?如果要修改一个用户创建的文件和目录的默认权限该如何做?本文将介绍相关的内容.说明:本文的演示环境为 ubuntu 16.04. 文件的默认权限 为了查看用户创建 ...
- Linux Namespace : PID
PID namespace 用来隔离进程的 PID 空间,使得不同 PID namespace 里的进程 PID 可以重复且互不影响.PID namesapce 对容器类应用特别重要, 可以实现容器内 ...
- Linux下部署Samba服务环境的操作记录
关于Linux和Windows系统之间的文件传输,很多人选择使用FTP,相对较安全,但是有时还是会出现一些问题,比如上传文件时,文件名莫名出现乱码,文件大小改变等问题.相比较来说,使用Samba作为文 ...
- MongoDB集群运维笔记
前面的文章介绍了MongoDB副本集和分片集群的做法,下面对MongoDB集群的日常维护操作进行小总结: MongDB副本集故障转移功能得益于它的选举机制.选举机制采用了Bully算法,可以很方便从分 ...
- Bing词典分析
0x01 Bug测试结果 本次测试的是Bing词典wp版本V4.5.2,经过测试,共发现如下Bug. 1.更新后,旧版本首页的每日单词与文章推荐不能重新获得,部分搜索历史记录丢失. 2.在单词挑战模式 ...
- Git学习笔记 第二章
文件相关操作 修改readme.txt文件,执行 git status 命令查看当前仓库状态 git status 位于分支 master 尚未暂存以备提交的变更: (使用 "git add ...
- 第七组团队项目——专业课程资源共享平台——需求分析&原型设计
一.项目目标.定位需求: (1)目标:在教师.学生之间建立一个综合的.全面的.快捷的.高效的免费课程和学习资源共享.交流与推荐的开放性平台,实现多维和动态的推荐与分类检索服务. (2)定位:学生与教师 ...
- <构建之法>10,11,12章的读后感
第十章:典型用户和场景 问题 :什么是典型用户? 第十一章:软件设计与实现 问题 :开发人员的标准工作流程就是不断的发现BUg,修改bug来完善功能,在此过程中要等待同伴复审,在这阶段中,开发者应该如 ...