[cerc2017J]Justified Jungle
题目大意:删去k条边,树变为相等个点的连通分量,求所有正整数k。
解题关键:树dp,不必求因子。
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define maxn 1000006 int head[maxn],cnt,siz[maxn],v[maxn],n; struct edge{ int to,nxt; }e[maxn<<1]; void add_edge(int u,int v){ e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt++; } void dfs(int u,int fa){ siz[u]=1; for(int i=head[u];i!=-1;i=e[i].nxt){ int v=e[i].to; if(v==fa) continue; dfs(v,u); siz[u]+=siz[v]; } v[siz[u]]++; } bool check(int x){ x++; if(n%x) return 0; int w=n/x,sum=0; for(int i=w;i<=n;i+=w) sum+=v[i]; return sum==x; } int main(){ memset(head,-1,sizeof head); scanf("%d",&n); for(int i=0;i<n-1;i++){ int a,b; scanf("%d%d",&a,&b); add_edge(a,b); add_edge(b,a); } dfs(1,-1); for(int i=1;i<=n;i++){ if(check(i)) printf("%d ",i); } return 0; }