【题解】

  一眼可以想到一个类似二叉树后序遍历的贪心做法,然而这个做法在有相同数字的情况下是错误的。最简单的反例就是n=4,d={1,1,1,2},正解是1,1,2,1,而贪心是1,1,1,2. 所以这个贪心被叉掉了。

  我们先把d从大到小排序,然后我们用f[i]表示第i个位置之前(包括i位置)还能取的数的个数。第一个节点显然去第size[1]大的数字就好,如果有多个相等的,那么就取最右边的,因为这可以为后面的节点预留更大的数。当取好一个点的值之后,需要给它的子树预留数字;我们并不能确定子树中的每个节点分别取什么值,但是我们知道子树取的数字一定大于当前节点的数值,所以子树取的值一定在当前节点的数字前面。我们只需要把当前位置及其右边的f[i]减去size即可。每次需要确定一个节点i的取值时,我们只需要找到最大的数值val满足val所在位置右边的c[j]都大于size[i],如果有多个相等的val,我们还是取最右边的那个。要找到这样的val,我们在线段树上二分就可以了。

  需要注意的是,在计算到某个父亲的第一个孩子时,我们需要把父亲预留的位置加回来。

  

 #include<cstdio>
#include<algorithm>
#define N 500010
#define rg register
#define ls (u<<1)
#define rs (u<<1|1)
using namespace std;
int n,m,d[N],siz[N],pos[N],cnt[N];
double k;
struct tree{
int l,r,del,mn;
}a[N<<];
inline int read(){
int k=,f=; char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(''<=c&&c<='')k=k*+c-'',c=getchar();
return k*f;
}
inline int min(int x,int y){return x<y?x:y;}
inline bool cmp(int x,int y){return x>y;}
void build(int u,int l,int r){
a[u].l=l; a[u].r=r; int mid=(l+r)>>;
if(l<r) build(ls,l,mid),build(rs,mid+,r),a[u].mn=min(a[ls].mn,a[rs].mn);
else a[u].mn=l;
}
inline void pushdown(int u){
int d=a[u].del; a[u].del=;
a[ls].del+=d; a[rs].del+=d;
a[ls].mn+=d; a[rs].mn+=d;
}
void update(int u,int l,int d){
if(l<=a[u].l){
a[u].mn+=d; a[u].del+=d; return;
}
if(a[u].del) pushdown(u);
update(rs,l,d);
if(l<=((a[u].l+a[u].r)>>)) update(ls,l,d);
a[u].mn=min(a[ls].mn,a[rs].mn);
}
int find(int u,int l,int r,int v) {
if (l==r) {
if (a[u].mn>=v) return l; return l+;
}
if (a[u].del) pushdown(u);
int mid=(l+r)>>;
if (a[rs].mn>=v) return find(ls,l,mid,v);
return find(rs,mid+,r,v);
}
int fa(int x) {return x/k;}
int main(){
n=read(); scanf("%lf",&k); build(,,n);
for(rg int i=;i<=n;i++) d[i]=read();
sort(d+,d++n,cmp);
for(rg int i=n-;i;i--) if(d[i]==d[i+]) cnt[i]=cnt[i+]+;
for(rg int i=n;i;i--) siz[fa(i)]+=++siz[i];
for(rg int i=;i<=n;i++){
if(fa(i)&&fa(i)!=fa(i-)) update(,pos[fa(i)],siz[fa(i)]-);
pos[i]=find(,,n,siz[i]); pos[i]+=cnt[pos[i]]; pos[i]-=cnt[pos[i]]++;
update(,pos[i],-siz[i]);
}
for(rg int i=;i<=n;i++) printf("%d ",d[pos[i]]);
return ;
}

洛谷 4364 [九省联考2018]IIIDX的更多相关文章

  1. 洛谷 4364 [九省联考2018]IIIDX——“预留”的思路

    题目:https://www.luogu.org/problemnew/show/P4364 原来想了一个错误的思路,就是这样: solve( cr , l , r ) 表示 cr 为根的子树填 [ ...

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

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

  3. 洛谷P4364 [九省联考2018]IIIDX(线段树)

    传送门 题解看得……很……迷? 因为取完一个数后,它的子树中只能取权值小于等于它的数.我们先把权值从大到小排序,然后记$a_i$为他左边(包括自己)所有取完他还能取的数的个数.那么当取完一个点$x$的 ...

  4. 洛谷 P4363 [九省联考2018]一双木棋chess 解题报告

    P4363 [九省联考2018]一双木棋chess 题目描述 菲菲和牛牛在一块\(n\)行\(m\)列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落 ...

  5. 洛谷P4363 [九省联考2018]一双木棋chess 【状压dp】

    题目 菲菲和牛牛在一块n 行m 列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束. 落子的规则是:一个格子可以落子当且仅当这个 ...

  6. 洛谷 P4363 [九省联考2018]一双木棋chess 题解

    题目链接:https://www.luogu.org/problemnew/show/P4363 分析: 首先博弈,然后考虑棋盘的规则,因为一个子在落下时它的上面和左面都已经没有空位了,所以棋子的右下 ...

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

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

  8. 洛谷P4382 [八省联考2018]劈配(网络流,二分答案)

    洛谷题目传送门 说不定比官方sol里的某理论最优算法还优秀一点? 所以\(n,m\)说不定可以出到\(1000\)? 无所谓啦,反正是个得分题.Orz良心出题人,暴力有70分2333 思路分析 正解的 ...

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

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

随机推荐

  1. bzoj1047

    二维单调队列 rmq很明显会超时,如果这个序列是一维的,很明显就是个单调队列,现在就是把一维的单调队列转换为二维单调队列. 先求出每一列的窗口极值,然后对于每一行做单调队列,值就是之前求出每个位置结尾 ...

  2. C#面向过程之编译原理、变量、运算符

    .net基础:.net与C# .net是一个平台 c#是一门语言 .net的用途a.桌面应用程序 b.网站应用程序 c.专业游戏开发(XBOX360) d.嵌入式设备软件开发 e.智能手机APP开发 ...

  3. Python机器学习算法 — 决策树(Decision Tree)

    决策树 -- 简介         决策树(decision tree)一般都是自上而下的来生成的.每个决策或事件(即自然状态)都可能引出两个或多个事件,导致不同的结果,把这种决策分支画成图形很像一棵 ...

  4. codeforces 949C - Data Center Maintenance【tarjan】

    首先转换图论模型,把某个客户一个终端的维修时间(+1)%h之后和另一个终端维修时间一样,这样的两个终端连一条有向边,表示推后一个终端就必须推后另一个 然后tarjan缩点,一个scc里的终端是要一起推 ...

  5. Linux day01(二)虚拟机快照和克隆的用法介绍

    一:快照 优点:运行虚拟机后不用担心系统会被弄崩溃了,点击快照会立即恢复到初始状态 缺点:回滚会带来数据的丢失,所以要考虑数据恢复的成本和找回数据时进行操作的成本 1. 在导航栏中找虚拟机快照的小图标 ...

  6. 数组去重----es6&es5&数组对象去重

    es6方法: 普通数组: 1.使用Array.from(new Set(arr)); /* * @param oldArr 带有重复项的旧数组 * @param newArr 去除重复项之后的新数组 ...

  7. DFS HDU 5305 Friends

    题目传送门 /* 题意:每个点都要有偶数条边,且边染色成相同的两部分,问能有多少种染色方法 DFS+剪枝:按照边数来DFS,每种染色数为该点入度的一半,还有如果点不是偶数边就不DFS 这是别人的DFS ...

  8. checkbox全选和取消功能

    这是开发中常见的小功能,想当初我也曾对于attr和prop的不了解踩过坑. 前端工作中,常常会使用到select复选框,select复选框有一个属性checked,当使用js或者jquery控制这个属 ...

  9. 235 Lowest Common Ancestor of a Binary Search Tree 二叉搜索树的最近公共祖先

    给定一棵二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 详见:https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-s ...

  10. SQL传入时间获取到时间的周一和周日

    declare @time datetime declare @timeMonday datetime set @time='2013-11-07' ) ,@time) select @timeMon ...