题目:https://www.luogu.org/problemnew/show/P4364

原来想了一个错误的思路,就是这样:

  solve( cr , l , r ) 表示 cr 为根的子树填 [ l , r ] 的数;然后把 l 给 cr ,剩下的 [ l+1 , r ] 分成一段一段,大的段给标号小的孩子。

然后只能得 60 分。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#define db double
#define pb push_back
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
const int N=5e5+;
int n,d[N],p[N],siz[N]; db k;
vector<int> vt[N];
void dfs(int cr)
{
siz[cr]=;
for(int i=,lm=vt[cr].size();i<lm;i++)
dfs(vt[cr][i]), siz[cr]+=siz[vt[cr][i]];
}
void solve(int cr,int l,int r)
{
p[cr]=d[l]; int p0=l;
for(int i=vt[cr].size()-;i>=;i--)
{
solve(vt[cr][i],p0+,p0+siz[vt[cr][i]]);
p0+=siz[vt[cr][i]];
}
}
int main()
{
n=rdn();scanf("%lf",&k);
for(int i=;i<=n;i++)d[i]=rdn();
sort(d+,d+n+);
for(int i=;i<=n;i++)
vt[(int)floor(i/k)].pb(i);
dfs(); solve(,,n);
for(int i=;i<=n;i++)printf("%d ",p[i]);
puts(""); return ;
}

看了看题解。https://files-cdn.cnblogs.com/files/NaVi-Awson/IIIDX.pdf

关于 “去掉父亲预留的影响” ,是这样考虑:

  按顺序枚举节点,在树上就是像 bfs 一样遍历;

  一个点 cr 要预留,是为了让 “和它深度相同的点” 不要抢了它的位置。

  当开始遍历 cr 的子树的时候,直接去掉 cr 的影响并再也不加入了;这样不会有错,因为此时不会再遍历和 cr 深度相同的点了;

  下一层的点已经由它们的父亲留好了位置,所以去掉 cr 的影响也不会让之后的点出错。

还有一种不太能理解的做法:https://www.cnblogs.com/HocRiser/p/8742680.html

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#define ls Ls[cr]
#define rs Rs[cr]
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
int Mn(int a,int b){return a<b?a:b;}
int Mx(int a,int b){return a>b?a:b;}
const int N=5e5+,M=N<<;
int n,a[N],fa[N],ans[N],siz[N],tp[N],tx[N];
int tot,Ls[M],Rs[M],mn[M],tg[M];
void pshp(int cr){mn[cr]=Mn(mn[ls],mn[rs]);}
void build(int l,int r,int cr)
{
if(l==r){mn[cr]=n-l;return;}
int mid=l+r>>;
ls=++tot; build(l,mid,ls);
rs=++tot; build(mid+,r,rs);
pshp(cr);
}
void pshd(int cr)
{
if(!tg[cr])return; int w=tg[cr]; tg[cr]=;
tg[ls]+=w; tg[rs]+=w; mn[ls]+=w; mn[rs]+=w;
}
void mdfy(int l,int r,int cr,int L,int R,int k)
{
if(l>=L&&r<=R){tg[cr]+=k;mn[cr]+=k;return;}
int mid=l+r>>; pshd(cr);
if(L<=mid)mdfy(l,mid,ls,L,R,k);
if(mid<R)mdfy(mid+,r,rs,L,R,k);
pshp(cr);
}
int qry(int l,int r,int cr,int k)
{
if(l==r)return mn[cr]>=k?l:-;
int mid=l+r>>,ret=-; pshd(cr);
if(mn[ls]>=k)ret=qry(mid+,r,rs,k);
if(ret>=)return ret;
return qry(l,mid,ls,k);
}
int main()
{
n=rdn(); double sl; scanf("%lf",&sl);
for(int i=;i<=n;i++)a[i]=rdn();
sort(a+,a+n+);
for(int i=;i<=n;i++)tp[i]=a[i];
int m=unique(tp+,tp+n+)-tp-;
for(int i=;i<=n;i++)
{
a[i]=lower_bound(tp+,tp+m+,a[i])-tp;
tx[a[i]]++;
}
for(int i=;i<=m;i++)tx[i]+=tx[i-];
for(int i=;i<=n;i++) fa[i]=floor(i/sl);
for(int i=n;i;i--) siz[i]++,siz[fa[i]]+=siz[i];
tot=; build(,n,);
for(int i=;i<=n;i++)
{
if(i>&&fa[i]!=fa[i-])
mdfy(,n,,,ans[fa[i]]-,siz[fa[i]]-);
//-1 for already use
int p=qry(,n,,siz[i])+;
p=++tx[a[p]-];//
ans[i]=p;
mdfy(,n,,,p-,-siz[i]);
}
for(int i=;i<=n;i++)printf("%d ",tp[a[ans[i]]]);
puts(""); return ;
}

洛谷 4364 [九省联考2018]IIIDX——“预留”的思路的更多相关文章

  1. 洛谷 4364 [九省联考2018]IIIDX

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

  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. normalization 阅读笔记

    https://zhuanlan.zhihu.com/p/33173246 阅读笔记 1. normalization whiting - PCA 2. Internal Covariate Shif ...

  2. [Jedis] ERR wrong number of arguments for 'mget'

    看别人写的代码是件比较痛苦的事情,更加痛苦的是别人的代码出错还要负责调试好. 关于如何迅速定位问题和调试代码,我的一点感受是:逐行认真查看错误信息,在这些信息中找自己熟悉的内容(包括文件名.方法名等) ...

  3. 【Python】进程间共享实例

    #练习:进程间共享实例 import time,os import random from multiprocessing import Pool,Value,Lock,Manager from mu ...

  4. Python学习笔记第十四周

    目录: 一.HTML 1.概述 2.HTML 二.CSS 一.HTML 1.概述 HTML是英文Hyper Text Mark-up Lang(超文本标记语言)的缩写,他是一种制作万维网页面的标准语言 ...

  5. [LeetCode&Python] Problem 237. Delete Node in a Linked List

    Write a function to delete a node (except the tail) in a singly linked list, given only access to th ...

  6. RNN-LSTM-GRU-BIRNN

    https://blog.csdn.net/wangyangzhizhou/article/details/76651116 共三篇 RNN的模型展开后多个时刻隐层互相连接,而所有循环神经网络都有一个 ...

  7. 内存池技术(UVa 122 Tree on the level)

    内存池技术就是创建一个内存池,内存池中保存着可以使用的内存,可以使用数组的形式实现,然后创建一个空闲列表,开始时将内存池中所有内存放入空闲列表中,表示空闲列表中所有内存都可以使用,当不需要某一内存时, ...

  8. 什么是 JVM

    什么是 JVM 先来看下百度百科的解释: JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,JVM 是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算 ...

  9. EasyUI datagrid 查询、设置、提交 三

    查询 $(“#grid”).datagrid(“load”,{  a: $('#id').val(),b :$('#text').val() });   {} 里面可以 是序列化参数 $(“#grid ...

  10. react 简书开发笔记

    详见文章<React简书开发实战课程笔记>