题目: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. dos命令:网络相关命令

    网络相关命令 一.Arp命令 1.介绍 ​ 显示和修改地址解析协议(ARP)使用的“IP 到物理”地址转换表. 2.语法 ARP -s inet_addr eth_addr [if_addr] ARP ...

  2. Could not load driverClass com.mysql.jdbc.Driver错误

    在整合spring和mybatis的时候,在spring配置文件中已经加载了db.properties并配置了c3p0数据源 但在写了一个测试类测试是否取到了数据库的连接时,报错:Could not ...

  3. 利用python将数据转存入sqlite3

    案例的目标是将存在文件中的json格式数据转存到sqlite数据库中.因此,需要利用python逐行读取json文件中数据,对数据进行解析和入库.具体操作步骤如下: 1.逐行读取json文件 for ...

  4. Python 类方法

    class Person: # 实例方法 def chi(self): print("人会吃") @classmethod # 装饰器, 此时这个方法是一个类方法 def he(c ...

  5. Redis过期策略(转)

    1.设置过期时间 expire key time(以秒为单位)--这是最常用的方式 setex(String key, int seconds, String value)--字符串独有的方式 具体的 ...

  6. HTML5的一些知识点

    1.新增很多api,比如获取用户的地理位置的window.navigator.geoloaction,history,audio,video,canvas 2.websocket;websocket是 ...

  7. 简易计算器的java实现

    伪代码 public class MainTestwei { 定义两个数组,List<Double> number和 List<Character>calculation分别用 ...

  8. 2017.4.4 TCP/IP三次握手,四次挥手

    之前在电话面试的时候,被问到,所以找到一个超级容易理解的图片,自己保存,也算分享.

  9. django-models层

    ----https://www.cnblogs.com/liuqingzheng/articles/9472723.html 一.ORM简介 查询数据层次图解:如果操作mysql,ORM是在pymys ...

  10. centos6下安装opencv3

    环境 centos6.5 opencv3.3.0 python3.4.9 下载 opencv可从GitHub下载https://github.com/opencv/opencv/tree/3.4.3可 ...