[启发式合并 DP] Atcoder ARC086E. Smuggling Marbles

比赛的时候想到了每层独立,但是不会搞…

官方题解

好像学到了关于深度的信息启发式合并的次数是 O(n) 的…
还有deque这种神奇的东西……像我以前都是set加上各种外层的标记……

果然还是太弱了

#include 
#include 
#include 
#include 

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 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;j1LL*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;i0;
  }
  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;i0].size();i++)
    ans=(ans+f[0][i].x)%P;
  ans=1LL*ans*Pow(2,n+1)%P;
  printf("%d\n",ans);
  return 0;
}

你可能感兴趣的:(DP,启发式合并)