洛谷 4364 [九省联考2018]IIIDX——“预留”的思路
题目: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——“预留”的思路的更多相关文章
- 洛谷 4364 [九省联考2018]IIIDX
[题解] 一眼可以想到一个类似二叉树后序遍历的贪心做法,然而这个做法在有相同数字的情况下是错误的.最简单的反例就是n=4,d={1,1,1,2},正解是1,1,2,1,而贪心是1,1,1,2. 所以这 ...
- 洛谷P4364 [九省联考2018]IIIDX 【线段树】
题目 [题目背景] Osu听过没?那是Konano最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在 ,他在世界知名游戏公司KONMAI内工作,离他的梦想也越来越近了.这款 ...
- 洛谷P4364 [九省联考2018]IIIDX(线段树)
传送门 题解看得……很……迷? 因为取完一个数后,它的子树中只能取权值小于等于它的数.我们先把权值从大到小排序,然后记$a_i$为他左边(包括自己)所有取完他还能取的数的个数.那么当取完一个点$x$的 ...
- 洛谷 P4363 [九省联考2018]一双木棋chess 解题报告
P4363 [九省联考2018]一双木棋chess 题目描述 菲菲和牛牛在一块\(n\)行\(m\)列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落 ...
- 洛谷P4363 [九省联考2018]一双木棋chess 【状压dp】
题目 菲菲和牛牛在一块n 行m 列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束. 落子的规则是:一个格子可以落子当且仅当这个 ...
- 洛谷 P4363 [九省联考2018]一双木棋chess 题解
题目链接:https://www.luogu.org/problemnew/show/P4363 分析: 首先博弈,然后考虑棋盘的规则,因为一个子在落下时它的上面和左面都已经没有空位了,所以棋子的右下 ...
- [luogu] P4364 [九省联考2018]IIIDX(贪心)
P4364 [九省联考2018]IIIDX 题目背景 Osu 听过没?那是Konano 最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在,他在世界知名游戏公司KONMAI ...
- 洛谷P4382 [八省联考2018]劈配(网络流,二分答案)
洛谷题目传送门 说不定比官方sol里的某理论最优算法还优秀一点? 所以\(n,m\)说不定可以出到\(1000\)? 无所谓啦,反正是个得分题.Orz良心出题人,暴力有70分2333 思路分析 正解的 ...
- BZOJ.5249.[九省联考2018]iiidx(贪心 线段树)
BZOJ LOJ 洛谷 \(d_i\)不同就不用说了,建出树来\(DFS\)一遍. 对于\(d_i\)不同的情况: Solution 1: xxy tql! 考虑如何把这些数依次填到树里. 首先对于已 ...
随机推荐
- git工具学习
最近实习的时候,遇到git工具,发现好强大之前没用过,特来学习下,然后自己注册了一个github账号,结合git命令练习一下,git的安装就不说了. 学习资料来源:廖雪峰Git教程 git简介: gi ...
- css 利用border 绘制三角形. triangle
1.基础三角形. <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- php优秀框架codeigniter学习系列——前言
php的框架众多,笔者用过的包括thinkphp,CI,smarty,laravel,也用过一些公司自己开发的框架. thinkphp是国人自己开发的,我大概用过一段时间,基本功能都还好,应该也还比较 ...
- kbmMW SmartService控制返回类型
- [工作日志] 2018-12-06 重点: 解决安全测试bug
安全测试bug 业务端提出, 在修改是否给联系人发送短信接口,如果操作人和被操作的联系人不在同一个企业的情况下, 也是可以修改的. 解决办法: 加校验.
- OAuth和OpenID的区别
OAuth关注的是authorization:而OpenID侧重的是authentication.从表面上看,这两个英文单词很容易混淆,但实际上,它们的含义有本质的区别: authorization: ...
- Quartz 原理
Quartz API :http://www.quartz-scheduler.org/api/2.2.0/ http://www.boyunjian.com/javadoc/org.apache.s ...
- [转]SSH反向连接及Autossh
http://www.cnblogs.com/eshizhan/archive/2012/07/16/2592902.html SSH反向连接及Autossh 0.接触Linux恐怕对SSH再熟悉不过 ...
- 倍增求lca
/* 节点维护的信息多样 如果用树状数组维护到根节点的边权或者点权, 可以直接插入点权和边权值,不需要预处理, 但是记得一定要使用ot[]消除影响.即差分. Housewife Wind 这个坑踩得死 ...
- python三大框架之一flask应用
创建一个python项目 第一步:打开pytharm 第二步:创建pure python 类型的项目 第三步:创建项目完成之后选择之前创建的py3_flack 作为虚拟环境 第四步:路径可以通过在制定 ...