【HNOI2018】排列

【HNOI2018】排列

img
img
img
img

神仙贪心题。

题目说这么大堆东西就是想告诉你这是个森林,选了\(v\)的父亲后才能选\(v\)

我们设\(w_v\)\(v\)所在联通块权值和,\(size_v\)表示\(v\)所在联通块的大小。

我们先考虑单点\(v\)。如果\(v\)是最小的点,那么我们尽量早地将它选了。也就是在选了\(v\)的父亲后就立即选\(v\)。所以我们可以将\(v\)与他的父亲合为一个联通块。

这个结论对于联通块也是成立的,只不过我们要比较平均值。

对于联通块\(u\),\(v\),如果\(u\)的优先级大于\(v\),则:

\[w_u+size_u\cdot w_v<w_v+size_v\cdot w_u\\ \Rightarrow \frac{w_u}{size_u}<\frac{w_v}{size_v} \]

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 500005
#define eps 1e-10

using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}

int n;
int a[N];
ll w[N];
int f[N],fa[N];
int Getf(int v) {return v==f[v]?v:f[v]=Getf(f[v]);}
int size[N];

struct node {
	ll w,s;
	int id;
	node() {w=s=id=0;}
	node(ll x,ll z,int y) {w=x,s=z,id=y;}
	bool operator <(const node &a)const {
		if(w*a.s!=a.w*s) return w*a.s>a.w*s;
		if(w!=a.w) return w<a.w;
		if(s!=a.s) return s<a.s;
		return id>a.id;
	}
};
bool operator ==(const node &a,const node &b) {return a.id==b.id&&a.w==b.w&&a.s==b.s;}

struct heap {
	priority_queue<node>add,del;
	void Insert(node tem) {add.push(tem);}
	void Pop() {while(del.size()&&(del.top())==(add.top())) del.pop(),add.pop();}
	void Del(node tem) {
		Pop();
		del.push(tem);
	}
	node Top() {
		Pop();
		return add.top();
	}
}S;
set<node>s;
node tem;

int main() {
	n=Get();
	for(int i=1;i<=n;i++) f[i]=i;
	for(int i=1;i<=n;i++) a[i]=Get();
	for(int i=1;i<=n;i++) w[i]=Get();
	for(int i=1;i<=n;i++) {
		if(Getf(a[i])==Getf(i)) {cout<<-1;return 0;}
		f[Getf(a[i])]=Getf(i);
	}
	ll ans=0;
	for(int i=0;i<=n;i++) f[i]=i;
	for(int i=1;i<=n;i++) {
		size[i]=1;
		S.Insert(node(w[i],1,i));
		ans+=w[i];
	}
	for(int i=1;i<=n;i++) {
		tem=S.Top();
		S.Del(tem);
		int now=tem.id;
		int fa=Getf(a[now]);
		if(fa) S.Del(node(w[fa],size[fa],fa));
		ans+=size[fa]*w[now];
		w[fa]+=w[now];
		size[fa]+=size[now];
		if(fa) S.Insert(node(w[fa],size[fa],fa));
		f[now]=Getf(fa);
	}
	cout<<ans;
	return 0;
}

posted @ 2019-03-15 22:10  hec0411  阅读(318)  评论(0编辑  收藏  举报