-
分類討論有點 ,考慮 表示把 是當前的左上角,且之前的全部填滿,將 的子樹填進去的方案數
-
如果兒子個數爲 1,那麼存在以下情況
-
係數分別是 ,合法的鏈滿足只有中間兩個點兒子個數不爲 1,其餘兒子數均爲 1 或 0,這個可以預處理出來 -
如果兒子個數爲 2,考慮哪個在上哪個在右即可轉移,和上一類的最後一種類似
複雜度
#include<bits/stdc++.h>
#define cs const
#define pb push_back
#define fi first
#define se second
using namespace std;
namespace IO{
cs int Rlen=1<<22|1;
inline char gc(){
static char buf[Rlen],*p1,*p2;
(p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin));
return p1==p2?EOF:*p1++;
}
int read(){
int x=0; bool f=false; char c=gc();
while(!isdigit(c)) f=c=='-', c=gc();
while(isdigit(c)) x=(((x<<2)+x)<<1)+(c^48), c=gc();
return f?-x:x;
}
} using namespace IO;
cs int Mod = 1e9 + 7;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; }
int dec(int a, int b){ return a - b < 0 ? a - b + Mod : a - b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
void Add(int &a, int b){ a = add(a,b); }
void Dec(int &a, int b){ a = dec(a,b); }
void Mul(int &a, int b){ a = mul(a,b); }
typedef pair<int, int> pi;
cs int N = 3e5 + 50;
int n; vector<int> G[N];
int ch[N][2], fa[N], dep[N];
void pre_dfs(int u, int f){
for(int v : G[u]) if(v ^ f)
fa[v]=u, dep[v]=dep[u]+1, pre_dfs(v,u);
} int dp[N];
vector<pi> S[N];
int len[N]; // to leaf
int Sublen[N]; // to key point
int bot[N];
vector<int> pt[N];
void pre_work(){
memset(len,-1,sizeof(len));
for(int i=1; i<=n; i++)
if(G[i].size()==0){
int x=i, d=1;
while(x){ len[x]=d; bot[x]=i; pt[i].pb(x); x=fa[x]; ++d; if(G[x].size()>1) break; }
}
static int id[N];
for(int i=1; i<=n; i++) id[i]=i;
sort(id+1, id+n+1, [](cs int &i, cs int &j){ return dep[i] > dep[j]; });
for(int i=1; i<=n; i++){
int u=id[i]; if(~len[u]) continue;
if(G[u].size()>1) continue;
if(Sublen[u]) continue; int d=1,x=u;
while(u){ Sublen[u]=d; bot[u]=x; pt[x].pb(u); u=fa[u]; ++d; if(G[u].size()>1) break; }
}
for(int u=1; u<=n; u++)if(Sublen[u] && len[u]==-1){
int v=G[bot[u]][0]; assert(G[v].size()==2);
for(int w : G[v])
for(int z : G[w])
if(len[z] == Sublen[u]) S[u].pb(pi(w,z));
for(int w : G[v]) if(len[w] == Sublen[u]-1) S[u].pb(pi(v,w));
}
}
int get(int u, int v){
assert(G[u].size()==2);
return G[u][0]==v ? G[u][1] : G[u][0];
}
int pnt(int v1, int v2){
if(len[v1]<len[v2]) swap(v1,v2);
assert(len[v1]!=len[v2]);
return pt[bot[v1]][len[v1]-len[v2]-1];
}
int sec_pnt(int v, int len){
return G[pt[bot[v]][Sublen[v]-len]][0];
}
void spc_work(int u, int v1, int v2){
if(len[v1]==-1 && len[v2]==-1) return;
if(~len[v1] && ~len[v2]){
if(len[v1]==len[v2]) Add(dp[u],1);
else Add(dp[u],dp[pnt(v1,v2)]);
}
else{
if(~len[v2]) swap(v1,v2);
if(len[v1]<=Sublen[v2]) Add(dp[u],dp[sec_pnt(v2,len[v1])]);
}
}
void work1(int u){
int v = G[u][0];
if(G[v].size()==0) return dp[u]=2,void();
if(G[v].size()==1) Add(dp[u],dp[G[v][0]]);
Add(dp[u],dp[v]);
if(~len[u] && ((len[u]&1)^1)) return Add(dp[u],1),void();
for(auto T : S[u]){
int t = T.fi, son = T.se;
if(G[t].size() == 1){
int v = get(fa[t],t);
Add(dp[u], dp[v]);
}
else{
if(G[fa[t]].size() == 1){
int v = get(t,son);
Add(dp[u], dp[v]);
}
else{
int v1 = get(fa[t],t), v2 = get(t,son);
spc_work(u,v1,v2);
}
}
}
}
void calc(int u, int v1, int v2){
if(G[v1].size()==0) return Add(dp[u],dp[v2]),void();
if(G[v1].size()==2) return; v1=G[v1][0];
spc_work(u,v2,v1);
}
void work2(int u){
int v1=G[u][0], v2=G[u][1];
if(len[v1]==-1 && len[v2]==-1) return;
calc(u,v1,v2); calc(u,v2,v1);
}
void work(int u){
for(int v : G[u]) if(v) work(v);
if(G[u].size()==0) dp[u]=1;
if(G[u].size()==1) work1(u);
if(G[u].size()==2) work2(u);
}
int main(){
#ifdef FSYolanda
freopen("1.in","r",stdin);
#endif
n=read();
for(int i=1,x,y; i<n; i++)
x=read(), y=read(), G[x].pb(y), G[y].pb(x);
pre_dfs(1,0); if(G[1].size()>2) return puts("0"),0;
for(int i=1; i<=n; i++){
if(G[i].size()>3) return puts("0"),0; vector<int> tmp;
for(int t : G[i]) if(t ^ fa[i]) tmp.pb(t); G[i] = tmp;
} pre_work();
work(1); cout<<dp[1]; exit(0); return 0;
}