[HNOI/AHOI2018]排列
如果\(a[i]=j\)则序列\(p[]\)中\(j\)必须排在\(i\)前面,如果\(j\)不在范围内则不管,求一个式子\(\sum_{i=1}^n iw_{p[i]}\)的最大值
考虑建出一个图,连边\(k=a_j\to j\)方向表示顺序,这样\([1,n]\)每个点的入度都会是\(1\)
如果有环那么就无解,否则这个图就是一棵以\(0\)为根树,如果是在树上的话,也就是说必须要先选父亲才能选儿子
考虑一种贪心
考虑一个当前权值最小的点\(i\)
\(1.\)如果\(i\)没有父亲\((fa[i]=0)\),那么我们当前一定是选\(i\)
\(2.\)如果\(i\)有父亲,那么当\(fa[i]\)选了后我们一定会最先选\(i\)
也就是说在最后的排列中\(fa[i]\)和\(i\)是挨在一块的,但是考虑到实际上多次合并后每个节点就是一个序列
手模以后发现,平均权值小的放前面答案会更优
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cassert>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long LL;
typedef long double ld;
const int INF=1e9+7;
typedef pair<ld,int> pdi;
inline LL read(){
register LL x=0,f=1;register char c=getchar();
while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f*x;
}
const int MAXN=5e5+5;
LL w[MAXN],done[MAXN];
int Fa[MAXN],a[MAXN];
int n;LL ans;
priority_queue <pdi,vector<pdi>,greater<pdi> > q,t;
inline int getfa(int x){return Fa[x]==x?x:Fa[x]=getfa(Fa[x]);}
int main(){
n=read();
for(int i=1;i<=n;i++) Fa[i]=i;
for(int i=1;i<=n;i++){
a[i]=read();
int fx=getfa(i),fy=getfa(a[i]);
if(fx==fy){printf("-1\n");return 0;}
Fa[fx]=fy;//直接用并查集判环
}
for(int i=1;i<=n;i++)
ans+=(w[i]=read());//先加一遍
for(int i=0;i<=n;i++) Fa[i]=i;
for(int i=1;i<=n;i++){
done[i]=1;
q.push(pdi((ld)w[i],i));
}
for(int i=1;i<=n;i++){
while(!t.empty()&&q.top()==t.top()){//每次删掉q.top(),可以保证正确性
t.pop();q.pop();
}
int x=q.top().second;q.pop();
assert(x==Fa[x]);
int y=getfa(a[x]);
if(y) t.push(pdi((ld)w[y]*1.0/done[y],y));//删掉
ans+=w[x]*done[y];//之前已经选了多少个,现在就接着选
w[y]+=w[x],done[y]+=done[x],Fa[x]=y;//合并个数到上一层(y可以等于0)
if(y) q.push(pdi((ld)w[y]*1.0/done[y],y));//更新
}
printf("%lld\n",ans);
}
[HNOI/AHOI2018]排列的更多相关文章
- 【LG4437】[HNOI/AHOI2018]排列
[LG4437][HNOI/AHOI2018]排列 题面 洛谷 题解 题面里这个毒瘤的东西我们转化一下: 对于\(\forall k,j\),若\(p_k=a_{p_j}\),则\(k<j\). ...
- [HNOI/AHOI2018]排列 贪心
题面 题解: 把题面的限制换成中文: 如果排在第k位的下标 = 排在第j位的值 ,那么k < j 换一个描述方式: 一个值为x的数要排在第x个数后面. 再换一个描述方式: \(fa[i] = a ...
- 洛谷 P4437 [HNOI/AHOI2018]排列(贪心+堆,思维题)
题面传送门 开始 WA ycx 的遗产(bushi 首先可以将题目转化为图论模型:\(\forall i\) 连边 \(a_i\to i\),然后求图的一个拓扑序 \(b_1,b_2,\dots b_ ...
- BZOJ5289 HNOI/AHOI2018排列(贪心+堆)
题面描述的相当绕,其实就是如果ai=j,重排后ai要在aj之后.同时每个ai有附属属性wi,要求最大化重排后的Σiwi. 容易发现这事实上构成一张图,即由j向i连边.由于每个点入度为1或0,该图是基环 ...
- 【洛谷 P4437】 [HNOI/AHOI2018]排列(贪心,堆)
题目链接 如果\(j<=k,a_{p[j]}!=p[k]\)可以理解为如果\(a_{p[j]}=p[k]\),那么\(k\)一定要放在\(j\)前面,也就是\(a_j\)在\(j\)前面. 于是 ...
- BZOJ5289 & 洛谷4437:[HNOI/AHOI2018]排列——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5289 https://www.luogu.org/problemnew/show/P4437 考虑 ...
- Poj2054 color a tree && [HNOI/AHOI2018]排列
https://zybuluo.com/ysner/note/1120723 题面 原题 某省选强化题 大致意思是给你一颗树,选父亲后才能选儿子. 每个点对答案的贡献为你在第几次选这个点 × 该点权值 ...
- luogu P4437 [HNOI/AHOI2018]排列
luogu 问题本质是把\(a_i\)作为\(i\)的父亲,然后如果有环就不合法,否则每次要取数,要满足取之前他的父亲都被取过(父亲为0可以直接取),求最大价值 贪心想法显然是要把权值大的尽量放在后面 ...
- 【题解】Luogu P4436 [HNOI/AHOI2018]游戏
原题传送门 \(n^2\)过百万在HNOI/AHOI2018中真的成功了qwqwq 先将没门分格的地方连起来,枚举每一个块,看向左向右最多能走多远,最坏复杂度\(O(n^2)\),但出题人竟然没卡(建 ...
随机推荐
- map两种插入方法解析(insert() 与 下标[]操作)
insert 含义是: 如果key存在,则插入失败,如果key不存在,就创建这个key-value. 实例: map.insert((key, value)) 利用下标操作的含义是: 如果这个key存 ...
- python学习路线以及视频下载
作者:林其链接:https://www.zhihu.com/question/19660572/answer/194904019来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- 百度Ueditor编辑器取消多图上传对话框中的图片搜索
百度Ueditor确实是一个非常强悍的编辑器,功能强大!但是实际开发需求复杂,总会有各种不符合要求的,比如想要取消多图上传的“图片搜索”选项卡(这个图片搜索真心难用)! 以ueditor 1.4.3为 ...
- Docker学习笔记_安装和使用mysql
一.系统环境和准备 1.宿主机OS:Win10 64位 2.虚拟机OS:Ubuntu18.04 3.操作账号:docker 二.安装 1.搜索mysql镜像:docker search mysql 2 ...
- Yii2验证登录得User类
Yii2中的 Class yii\web\User 是如果进行验证登录,如果我们使用User类验证登录会给我们减少很多麻烦.在此就拿Yii2中自带的登录功能进行说明. 配置.在应用配置文件compo ...
- Swing滚动条重写
Swing滚动条重写 摘自:https://blog.csdn.net/qq_40064948/article/details/81738191 未验证 Swing滚动条重写 2018年08月16日 ...
- js-简单的作业
作业 1 将课堂 偶数奇数和 猜数字游戏 电话银行转for循环 2 编写 “个人所得税计算器”函数 10000 计算个税的方法: 3500 以下免征 6500 3500 ~ 5000 部分 缴纳 3% ...
- Build fat static library (device + simulator) using Xcode and SDK 4+
155down votefavorite 185 It appears that we can - theoretically - build a single static library that ...
- OpenSSH/PuTTY/SSH使用
OpenSSH/PuTTY/SSH 常用SSH服务指令 ① 启动SSH服务的命令 service sshd start ② 停止SSH服务的命令 service sshd stop ③ 重新启动SSH ...
- wc.exe C++实现
目录 Github项目地址 PSP表格 解题思路 设计实现过程 测试运行 项目小结 Github项目地址 wc-project PSP表格 PSP2.1 Personal Software Proce ...