[BZOJ5249][九省联考2018]IIIDX:线段树+贪心
分析
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:线段树+贪心的更多相关文章
- [九省联考2018] IIIDX 线段树+贪心
题目: 给出 k 和 n 个数,构造一个序列使得 d[i]>=d[i/k] ,并且字典序最大. 分析: 听说,当年省选的时候,这道题挡住了大批的高手,看上去十分简单,实际上那道弯段时间内是转不过 ...
- [BZOJ5249][九省联考2018]IIIDX(线段树)
5249: [2018多省省队联测]IIIDX Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 32 Solved: 17[Submit][Statu ...
- BZOJ5249 九省联考2018IIIDX(线段树+贪心)
显然这形成了一个树形结构.考虑这样一种贪心:按照曲目顺序,每次取消其父亲的预留,并选择当前可选择(保证其子树有合法选择且满足预留)的最大值,然后对其子树预留出大于等于他的一些值.这个做法显然是正确的. ...
- 省选九省联考T2 IIIDX(线段树)
题目传送门:https://www.luogu.org/problemnew/show/P4364 期中考后记:期中考刚考完,感觉不咋滴,年排第3.我抗压力太差了..期末得把rank1抢回来. 本来感 ...
- [luogu] P4364 [九省联考2018]IIIDX(贪心)
P4364 [九省联考2018]IIIDX 题目背景 Osu 听过没?那是Konano 最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在,他在世界知名游戏公司KONMAI ...
- [BZOJ 5252][LOJ 2478][九省联考2018] 林克卡特树
[BZOJ 5252][LOJ 2478][九省联考2018] 林克卡特树 题意 给定一个 \(n\) 个点边带权的无根树, 要求切断其中恰好 \(k\) 条边再连 \(k\) 条边权为 \(0\) ...
- BZOJ5249:[九省联考2018]IIIDX——题解
https://www.luogu.org/problemnew/show/P4364#sub https://www.lydsy.com/JudgeOnline/problem.php?id=524 ...
- 洛谷P4364 [九省联考2018]IIIDX 【线段树】
题目 [题目背景] Osu听过没?那是Konano最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在 ,他在世界知名游戏公司KONMAI内工作,离他的梦想也越来越近了.这款 ...
- BZOJ.5249.[九省联考2018]iiidx(贪心 线段树)
BZOJ LOJ 洛谷 \(d_i\)不同就不用说了,建出树来\(DFS\)一遍. 对于\(d_i\)不同的情况: Solution 1: xxy tql! 考虑如何把这些数依次填到树里. 首先对于已 ...
随机推荐
- B.super_log(The Preliminary Contest for ICPC Asia Nanjing 2019)
同:https://www.cnblogs.com/--HPY-7m/p/11444923.html #define IOS ios_base::sync_with_stdio(0); cin.tie ...
- Git 实习一个月恍然大悟合集
从开始实习到现在大概有一个月了,这个月时间接触了很多新东西,其中就包括了git版本控制.分支管理等等.我在这段时间里,深深地感受到了git对公司项目代码管理和控制.团队合作带来的益处和其重要性.其实在 ...
- JS获取url中的指定参数
function GetRequest() { var url = location.search; //获取url中"?"符后的字串 var theRequest = new O ...
- A Horrible Poem (字符串hash+数论)
# 10038. 「一本通 2.1 练习 4」A Horrible Poem [题目描述] 给出一个由小写英文字母组成的字符串 $S$,再给出 $q$ 个询问,要求回答 $S$ 某个子串的最短循环节. ...
- java保留小数点的几个方法
方法一: String类自带的方法 String.format("%.2f", 1.2548); "%.2f"其中的数字决定保留几位方法二: 格式化的方法 pr ...
- Gsview裁剪EPS文件
(1)菜单栏 “options--show bounding boxs” 选中. (2)打开eps图,然后File->PS TO EPS,不选择Automatically calculate ...
- Linux小知识:rm -rf/*会将系统全部删除吗
Linux小知识:rm -rf/*会将系统全部删除吗 本文是学习笔记,视频地址为:https://www.bilibili.com/video/av62839850 执行上面的命令并不会删除所有内容( ...
- [转载]static in Java
来源:https://www.cnblogs.com/chenssy/p/3386721.html 一. static代表着什么 在Java中并不存在全局变量的概念,但是我们可以通过static来实现 ...
- Vue中,过滤器的使用方法!
Vue.js允许自定义过滤器,可被用于一些常见的文本格式化.过滤器可以用在两个地方:双花括号插值和v-bind表达式.过滤器应该被添加在JavaScript表达式的尾部,由“管道”符号指示:(借官方的 ...
- jquery 滚动事件-记录自己常用的
1.h5端页面滑动至第3屏及以后才出现置顶按钮 $(document).scroll(function() { var scroH = $(document).scrollTop(); //滚动高度 ...