比赛的时候想到了每层独立,但是不会搞…
好像学到了关于深度的信息启发式合并的次数是
O(n)
的…
还有deque这种神奇的东西……像我以前都是set加上各种外层的标记……
果然还是太弱了
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int,int> par;
const int N=200010,P=1e9+7,inv2=P+1>>1;
int n,cnt,G[N],dpt[N];
struct edge{
int t,nx;
}E[N];
struct tp{
int x,y,z;
tp(){}
tp(int a,int b,int c):x(a),y(b),z(c){}
};
inline void addedge(int x,int y){
E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt;
}
inline int Pow(int x,int y){
int ret=1;
for(;y;y>>=1,x=1LL*x*x%P) if(y&1) ret=1LL*ret*x%P;
return ret;
}
deque<tp> f[N];
void dfs(int x){
int mx=0,smx=0;
for(int i=G[x];i;i=E[i].nx){
dfs(E[i].t); int v=E[i].t;
if(f[v].size()>mx) smx=mx,mx=f[v].size();
else smx=max(smx,(int)f[v].size());
if(f[v].size()>f[x].size()) swap(f[x],f[v]);
for(int j=0;j<f[v].size();j++){
tp cur;
cur.x=(1LL*f[x][j].x*f[v][j].y+1LL*f[v][j].x*f[x][j].y)%P;
cur.y=1LL*f[x][j].y*f[v][j].y%P;
cur.z=(1LL*f[x][j].x*f[v][j].x+1LL*f[x][j].x*f[v][j].z+1LL*f[x][j].y*f[v][j].z+1LL*f[x][j].z*f[v][j].x+1LL*f[x][j].z*f[v][j].y+1LL*f[x][j].z*f[v][j].z)%P;
f[x][j]=cur;
}
}
for(int i=0;i<smx;i++){
f[x][i].y=(f[x][i].y+f[x][i].z)%P;
f[x][i].z=0;
}
f[x].push_front(tp(inv2,inv2,0));
}
int main(){
scanf("%d",&n);
for(int i=1,x;i<=n;i++)
scanf("%d",&x),addedge(x,i);
dfs(0); int ans=0;
for(int i=0;i<f[0].size();i++)
ans=(ans+f[0][i].x)%P;
ans=1LL*ans*Pow(2,n+1)%P;
printf("%d\n",ans);
return 0;
}

本文探讨了一种使用深度信息启发式合并的方法,并通过Deque实现了高效的数据结构操作。介绍了如何利用启发式合并减少合并次数至O(n),并讨论了Deque在算法中的应用技巧。
205

被折叠的 条评论
为什么被折叠?



