生活随笔
收集整理的這篇文章主要介紹了
AGC023F - 01 on Tree
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
AGC023F - 01 on Tree
題目描述
Solution
有一個奇妙的貪心思路。(奇妙的原因是我不會證)
這一題的結(jié)點需要按拓撲序排序,并讓逆序?qū)€數(shù)最小。
考慮在兒子向父親合并的過程中統(tǒng)計答案,產(chǎn)生的逆序?qū)€數(shù)就是cnt[father][1]?cnt[son][0]cnt[father][1]*cnt[son][0]cnt[father][1]?cnt[son][0],其中cnt[x][0/1]cnt[x][0/1]cnt[x][0/1]表示xxx這個聯(lián)通塊已經(jīng)擁有的0/10/10/1結(jié)點的數(shù)量,我們貪心地選取cnt[x][0]cnt[x][1]\frac{cnt[x][0]}{cnt[x][1]}cnt[x][1]cnt[x][0]?最小的結(jié)點合并到父親,并堆維護這一過程就可以做到O(nlgn)O(nlgn)O(nlgn)求解答案。
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se secondusing namespace std
;template<typename T
>inline bool upmin(T
&x
,T y
) { return y
<x
?x
=y
,1:0; }
template<typename T
>inline bool upmax(T
&x
,T y
) { return x
<y
?x
=y
,1:0; }typedef long long ll
;
typedef unsigned long long ull
;
typedef long double lod
;
typedef pair
<int,int> PR
;
typedef vector
<int> VI
;const lod eps
=1e-11;
const lod pi
=acos(-1);
const int oo
=1<<30;
const ll loo
=1ll<<62;
const int mods
=998244353;
const int MAXN
=600005;
const int INF
=0x3f3f3f3f;
inline int read()
{int f
=1,x
=0; char c
=getchar();while (c
<'0'||c
>'9') { if (c
=='-') f
=-1; c
=getchar(); }while (c
>='0'&&c
<='9') { x
=(x
<<3)+(x
<<1)+(c
^48); c
=getchar(); }return x
*f
;
}
int cnt
[MAXN
][2],fa
[MAXN
],f
[MAXN
];
struct heapnode
{int x
,y
,id
;bool operator < (const heapnode
&a
) const { return 1ll*x
*a
.y
<1ll*y
*a
.x
; }
};
priority_queue
<heapnode
> heap
;
int find(int x
){ return f
[x
]==x
?f
[x
]:f
[x
]=find(f
[x
]); }
int main()
{int n
=read();for (int i
=2;i
<=n
;i
++) fa
[i
]=read();for (int i
=1;i
<=n
;i
++) {int x
=read();cnt
[i
][x
]++;f
[i
]=i
;}for (int i
=2;i
<=n
;i
++) heap
.push((heapnode
){cnt
[i
][0],cnt
[i
][1],i
});ll ans
=0;while (!heap
.empty()){int u
=find(heap
.top().id
),x
=heap
.top().x
,y
=heap
.top().y
; heap
.pop();if (cnt
[u
][0]==x
&&cnt
[u
][1]==y
){int v
=find(fa
[u
]);ans
+=1ll*cnt
[v
][1]*cnt
[u
][0];cnt
[v
][0]+=cnt
[u
][0];cnt
[v
][1]+=cnt
[u
][1];f
[u
]=v
;if (v
!=1) heap
.push((heapnode
){cnt
[v
][0],cnt
[v
][1],v
});}}printf("%lld\n",ans
);return 0;
}
總結(jié)
以上是生活随笔為你收集整理的AGC023F - 01 on Tree的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。