BZOJ5289 & 洛谷4437:[HNOI/AHOI2018]排列——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5289
https://www.luogu.org/problemnew/show/P4437
考虑对于a[i]=m,a[m]=n,我们令p[j]=i,p[k]=m(一定会有一对(j,k)满足这个条件的),则我们会有p[k]=a[p[j]],此时我们要满足k<j,也就是a[m]放的位置要比a[i]靠前。
也就是说选第m个之后才能选第i个。
转换成图论模型就是m->i <=> a[i]->i。
那么问题豁然开朗,首先如果图中有环就能判断无解了。
如果有解则必然为以0为根的有向树,则答案为每个节点i被拿到的时间*w[i](前提是i的父亲被拿才可以拿i)。
再考虑最大化答案,则我们让树中最小值min尽可能早的被拿到就好了。
继续贪心,则如果当前局面能够拿到min则一定拿min,换句话将就是拿了min的父亲就一定拿min。
那么父亲和min之间就成了捆绑关系,于是将其缩起来,在缩的过程中更新答案,然后递归这个过程就好了。
每次找min可以用堆维护,复杂度O(nlogn)。
(PS:更新答案,每次更新显然是这个点前面一些点被选了,于是它一定产生了前面这些点个数*w[该点]的价值)
那么就需要考虑我们缩完的点的w要怎么计算,对于两个集合a,b要合并,显然用在计算上的w=wa+wb,但是用堆排序的时候就不能这么做了。
自然能想到取平均值,虽然我不会证明,不过考量一下发现差不多。
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
typedef long long ll;
typedef long double dl;
typedef pair<dl,int>pii;
#define fi first
#define se second
typedef __gnu_pbds::priority_queue<pii,greater<pii>,__gnu_pbds::pairing_heap_tag> heap;
const int N=5e5+;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int to,nxt;
}e[N];
int n,cnt,head[N],vis[N],a[N],num,fa[N],size[N];
ll w[N],ans;
heap::point_iterator id[N];
heap q;
inline void add(int u,int v){
e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt;
}
bool dfs(int u){
vis[u]=;num++;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(vis[v]||!dfs(v))return ;
}
if(!u&&num<=n)return ;
return ;
}
inline int find(int x){
if(x==fa[x])return x;
return fa[x]=find(fa[x]);
}
int main(){
n=read();
for(int i=;i<=n;i++)a[i]=read(),add(a[i],i);
for(int i=;i<=n;i++)w[i]=read();
if(!dfs()){puts("-1");return ;}
for(int i=;i<=n;i++)fa[i]=i,size[i]=;
for(int i=;i<=n;i++)id[i]=q.push(pii(w[i],i));
while(!q.empty()){
int u=q.top().se,v=a[u];q.pop();
int rt=find(v);
ans+=w[u]*size[rt];
fa[u]=rt;w[rt]+=w[u];size[rt]+=size[u];
if(rt)q.modify(id[rt],pii((dl)w[rt]/size[rt],rt));
}
printf("%lld\n",ans);
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ5289 & 洛谷4437:[HNOI/AHOI2018]排列——题解的更多相关文章
- 洛谷 P4437 [HNOI/AHOI2018]排列(贪心+堆,思维题)
		题面传送门 开始 WA ycx 的遗产(bushi 首先可以将题目转化为图论模型:\(\forall i\) 连边 \(a_i\to i\),然后求图的一个拓扑序 \(b_1,b_2,\dots b_ ... 
- [Bzoj5285][洛谷P4424][HNOI/AHOI2018]寻宝游戏(bitset)
		P4424 [HNOI/AHOI2018]寻宝游戏 某大学每年都会有一次Mystery Hunt的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为新生 ... 
- 洛谷P4438 [HNOI/AHOI2018]道路(dp)
		题意 题目链接 Sol 每当出题人想起他出的HNOI 2018 Day2T3,他都会激动的拍打着轮椅 读题比做题用时长系列... \(f[i][a][b]\)表示从根到\(i\)的路径上,有\(a\) ... 
- 洛谷P4425 [HNOI/AHOI2018]转盘(线段树)
		题意 题目链接 Sol 首先猜一个结论:对于每次询问,枚举一个起点然后不断等到某个点出现时才走到下一个点一定是最优的. 证明不会,考场上拍了3w组没错应该就是对的吧... 首先把数组倍长一下方便枚举起 ... 
- 洛谷P4424 [HNOI/AHOI2018]寻宝游戏(思维题)
		题意 题目链接 Sol 神仙题Orz Orz zbq爆搜70.. 考虑"与"和"或"的性质 \(0 \& 0 = 0, 1 \& 0 = 0\) ... 
- [洛谷P4436] HNOI/AHOI2018 游戏
		问题描述 一次小G和小H在玩寻宝游戏,有n个房间排成一列,编号为1,2,...,n,相邻的房间之间都有一道门.其中一部分门上锁(因此需要有对应的钥匙才能开门),其余的门都能直接打开.现在小G告诉了小H ... 
- 洛谷 P4426 - [HNOI/AHOI2018]毒瘤(虚树+dp)
		题面传送门 神仙虚树题. 首先考虑最 trival 的情况:\(m=n-1\),也就是一棵树的情况.这个我相信刚学树形 \(dp\) 的都能够秒掉罢(确信).直接设 \(dp_{i,0/1}\) 在表 ... 
- 【LG4437】[HNOI/AHOI2018]排列
		[LG4437][HNOI/AHOI2018]排列 题面 洛谷 题解 题面里这个毒瘤的东西我们转化一下: 对于\(\forall k,j\),若\(p_k=a_{p_j}\),则\(k<j\). ... 
- 洛谷P1783  海滩防御 分析+题解代码
		洛谷P1783 海滩防御 分析+题解代码 题目描述: WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ... 
随机推荐
- hdu1969Pie(根据体积二分,分馅饼)
			Pie Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ... 
- hdu1203I NEED A OFFER!(01背包)
			I NEED A OFFER! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ... 
- 不老的神器--namp,awvs
			要会使用的工具 NESSUS nmap awvs hydra burpsuit 工具的话,都有文档,应该多使用 -h 多看官方文档,就会用了. 1.namp基本用法 -iL <inputfile ... 
- 第4章 TCP/IP通信案例:访问Internet上的Web服务器
			第4章 TCP/IP通信案例:访问Internet上的Web服务器 4.2 部署代理服务器 书中为了演示访问Internet上的Web服务器的全过程,使用了squid代理服务器程序模拟了一个代理服务器 ... 
- Python3 Tkinter-Message
			1.创建 from tkinter import * root=Tk() Message(root,text='hello Message').pack() root.mainloop() 2.属性 ... 
- vs2008 c#项目调试dll源码,问题:“若要调试此模块,请将其项目生成配置更改为“调试”模式” 的解决方案
			情况: 1:有程序 Trans.exe 的vs2008 c#源码:Trans.exe项目里引用了 Water.dll: 2:有Water.dll的项目源码: 3:想在Trans.exe里调试Water ... 
- BZOJ 3924 ZJOI2015 幻想乡战略游戏 树链剖分
			题目链接:https://www.luogu.org/problemnew/show/P3345(bzoj权限题) 题意概述:动态维护树的上所有点到这棵树的带权重心的距离和.N,Q<=10000 ... 
- c# 调取 c++ dll____c#调用dll
			1.以海康摄像头dll为例.(文章转载https://www.cnblogs.com/smartsensor/p/4343744.html) 海康SDK编程指南 目前使用的海康SDK包括IPC_SDK ... 
- OSG学习:移动/缩放/旋转模型
			移动和缩放以及旋转都是对矩阵进行操作,这些操作如果要叠加直接矩阵相乘就可以了. 下面的示例代码中,加入了四个bignathan,一个是默认加入在最中间,一个向上移2单位,一个是向下移2单位且缩放0.5 ... 
- oracle 11g ADG实施手册(亲测,已成功部署多次)
			一:实验环境介绍 虚拟机系统: RHEL Linux 6.4(64位) 数据库版本: Oracle 11gR2 11.2.0.4 (64位) IP地址规划: 主数据库 192.168.11 ... 
