题解--AT3721 [ARC086C] Smuggling Marbles
因为每一轮操作都会把石子深度减
对于
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int>::iterator iter;
const int maxn=2e5+5,mod=1e9+7;
struct edge {
int next,to;
} e[maxn*2];
int h[maxn],cnt,d[maxn],f[maxn][18],lg2[maxn],n,m,p[maxn],pos,st[maxn],top,mxd;
bool bj[maxn];
ll ans,f0[maxn],f1[maxn];
vector<int> b[maxn],v[maxn];
void addedge(int x,int y) {
e[++cnt].next=h[x],e[cnt].to=y,h[x]=cnt;
}
ll qpow(ll x,int y) {
ll w=1;
while(y) {
if(y&1)w=w*x%mod;
x=x*x%mod,y>>=1;
}
return w;
}
void dfs(int u,int fa) {
mxd=max(mxd,d[u]=d[fa]+1),b[d[u]].push_back(u),f[u][0]=fa,p[u]=++pos;
for(int i=1; i<=lg2[d[u]]; i++)f[u][i]=f[f[u][i-1]][i-1];
for(int i=h[u]; i; i=e[i].next)dfs(e[i].to,u);
}
int lca(int x,int y) {
if(d[x]<d[y])swap(x,y);
while(d[x]>d[y])x=f[x][lg2[d[x]-d[y]]-1];
if(x==y)return x;
for(register int i=lg2[d[x]]-1; i>=0; i--)
if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
return f[x][0];
}
void dp(int u) {
ll f2=0;
f0[u]=1,f1[u]=bj[u];
for(iter it=v[u].begin(); it!=v[u].end(); it++) {
dp(*it),f2=(f2*(f0[*it]+f1[*it])+f1[u]*f1[*it])%mod;
f1[u]=(f0[u]*f1[*it]+f1[u]*f0[*it])%mod,f0[u]=f0[u]*f0[*it]%mod;
}
f0[u]=(f0[u]+f2)%mod,v[u].clear();
}
bool cmp(int x,int y) {
return p[x]<p[y];
}
int main() {
int x;
scanf("%d",&n),n++;
for(int i=2; i<=n; i++)scanf("%d",&x),addedge(x+1,i);
dfs(1,0);
for(int i=1; i<=mxd; i++) {
sort(b[i].begin(),b[i].end(),cmp);
iter it=b[i].begin();
bj[*it]=1,st[top=1]=*(it++);
for(; it!=b[i].end(); it++) {
int la=lca(st[top],*it);
while(top) {
if(d[la]>=d[st[top-1]]) {
if(la!=st[top])v[la].push_back(st[top]),la!=st[top-1]?st[top]=la:top--;
break;
}
v[st[top-1]].push_back(st[top]),top--;
}
st[++top]=*it,bj[*it]=1;
}
while(--top)v[st[top]].push_back(st[top+1]);
dp(st[1]),ans=(ans+f1[st[1]]*qpow(2,n-b[i].size()))%mod;
it=b[i].begin();
for(; it!=b[i].end(); it++)bj[*it]=0;
}
printf("%lld",ans);
return 0;
}