[Luogu4437]

如果\(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]排列的更多相关文章

  1. 【LG4437】[HNOI/AHOI2018]排列

    [LG4437][HNOI/AHOI2018]排列 题面 洛谷 题解 题面里这个毒瘤的东西我们转化一下: 对于\(\forall k,j\),若\(p_k=a_{p_j}\),则\(k<j\). ...

  2. [HNOI/AHOI2018]排列 贪心

    题面 题解: 把题面的限制换成中文: 如果排在第k位的下标 = 排在第j位的值 ,那么k < j 换一个描述方式: 一个值为x的数要排在第x个数后面. 再换一个描述方式: \(fa[i] = a ...

  3. 洛谷 P4437 [HNOI/AHOI2018]排列(贪心+堆,思维题)

    题面传送门 开始 WA ycx 的遗产(bushi 首先可以将题目转化为图论模型:\(\forall i\) 连边 \(a_i\to i\),然后求图的一个拓扑序 \(b_1,b_2,\dots b_ ...

  4. BZOJ5289 HNOI/AHOI2018排列(贪心+堆)

    题面描述的相当绕,其实就是如果ai=j,重排后ai要在aj之后.同时每个ai有附属属性wi,要求最大化重排后的Σiwi. 容易发现这事实上构成一张图,即由j向i连边.由于每个点入度为1或0,该图是基环 ...

  5. 【洛谷 P4437】 [HNOI/AHOI2018]排列(贪心,堆)

    题目链接 如果\(j<=k,a_{p[j]}!=p[k]\)可以理解为如果\(a_{p[j]}=p[k]\),那么\(k\)一定要放在\(j\)前面,也就是\(a_j\)在\(j\)前面. 于是 ...

  6. BZOJ5289 & 洛谷4437:[HNOI/AHOI2018]排列——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5289 https://www.luogu.org/problemnew/show/P4437 考虑 ...

  7. Poj2054 color a tree && [HNOI/AHOI2018]排列

    https://zybuluo.com/ysner/note/1120723 题面 原题 某省选强化题 大致意思是给你一颗树,选父亲后才能选儿子. 每个点对答案的贡献为你在第几次选这个点 × 该点权值 ...

  8. luogu P4437 [HNOI/AHOI2018]排列

    luogu 问题本质是把\(a_i\)作为\(i\)的父亲,然后如果有环就不合法,否则每次要取数,要满足取之前他的父亲都被取过(父亲为0可以直接取),求最大价值 贪心想法显然是要把权值大的尽量放在后面 ...

  9. 【题解】Luogu P4436 [HNOI/AHOI2018]游戏

    原题传送门 \(n^2\)过百万在HNOI/AHOI2018中真的成功了qwqwq 先将没门分格的地方连起来,枚举每一个块,看向左向右最多能走多远,最坏复杂度\(O(n^2)\),但出题人竟然没卡(建 ...

随机推荐

  1. 【总结整理】OpenLayers项目分析,OpenLayers中的图层,GeoServer发布wms服务--实验(转)

    https://blog.csdn.net/u013751758/article/details/44751315 https://blog.csdn.net/u013751758/article/d ...

  2. Python中__new__与__init__介绍

    在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A()) 新式类跟经典类的差别主要是以下几点: 1 ...

  3. 一个小仓鼠的js动画

    直接在网页打开就可以玩了: http://cdn.abowman.com/widgets/hamster/hamster.swf?up_bodyColor=f0e9cc&up_feetColo ...

  4. win10手动开启wifi

    win+R键,输入cmd,以管理员身份运行,输入netsh wlan set hostednetwork mode=allow ssid=wifi key=wifimima123回车 解释一下: ss ...

  5. JSP内置对象与servlet对应关系

    隐式对象 说明 out 转译后对应JspWriter对象,其内部关联一个PringWriter对象 request 转译后对应HttpServletRequest/ServletRequest对象 r ...

  6. 实践作业3:白盒测试----开始测试用例的设计DAY3

    白盒测试与黑盒测试很大不同之处在于白盒测试必须读相应代码,对代码有一定了解的情况下针对代码的逻辑进行测试用例的设计.白盒测试有六种覆盖标准:语句覆盖.判定覆盖.条件覆盖.判定/条件覆盖.条件组合覆盖和 ...

  7. LightOJ 1284 Lights inside 3D Grid (数学期望)

    题意:在一个三维的空间,每个点都有一盏灯,开始全是关的.现在每次随机选两个点,把两个点之间的全部点,开关都按一遍,问k次过后开着的灯的期望数量: 析:很容易知道,如果一盏灯被按了奇数次,那么它肯定是开 ...

  8. repo相关命令

    1.repo start <topic_name> 开启一个新的主题,其实就是每个Project都新建一个分支. repo start newbranchname . 创建新的branch ...

  9. 小程序上传多图片多附件多视频 c#后端

    前言: 最近在研究微信小程序,本人自己是C#写后端的;感觉小程序挺好玩的,就自己研究了一下:刚好今天又给我需求,通过小程序上传多图 然后C#后端保存到服务器: 用NET明白 前端上传需要用到流,然后就 ...

  10. unix网络编程 str_cli epoll 非阻塞版本

    unix网络编程 str_cli epoll 非阻塞版本 unix网络编程str_cli使用epoll实现讲了使用epoll配合阻塞io来实现str_cli,这个版本是配合非阻塞io. 可以看到采用非 ...