JZOJ 4757. 树上摩托
Posted traveller-ly
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JZOJ 4757. 树上摩托相关的知识,希望对你有一定的参考价值。
Description
Sherco是一位经验丰富的魔♂法师。
Sherco在第零次圣杯战争中取得了胜利,并取得了王之宝藏——王の树。
他想把这棵树砍去任意条边,拆成若干棵新树,并装饰在他的摩托上,让他的摩托更加酷炫。
但Sherco认为,这样生成的树不具有美感,于是Sherco想让每棵新树的节点数相同。
他想知道有多少种方法分割这棵树。
Sherco在第零次圣杯战争中取得了胜利,并取得了王之宝藏——王の树。
他想把这棵树砍去任意条边,拆成若干棵新树,并装饰在他的摩托上,让他的摩托更加酷炫。
但Sherco认为,这样生成的树不具有美感,于是Sherco想让每棵新树的节点数相同。
他想知道有多少种方法分割这棵树。
Input
第一行一个正整数N,表示这棵树的结点总数。
接下来N-1行,每行两个数字X,Y表示编号为X的结点与编号为Y的结点相连。结点编号的范围为[1,N]。
接下来N-1行,每行两个数字X,Y表示编号为X的结点与编号为Y的结点相连。结点编号的范围为[1,N]。
Output
一个整数,表示方案数。注意,不砍去任何一条边也算作一种方案。
Sample Input
6
1 2
2 3
2 4
4 5
5 6
Sample Output
3
Data Constraint
对于40%的数据,N ≤ 15
对于60%的数据,N ≤ 10^5
对于100%的数据,N ≤ 10^6
数据规模非常大,请使用高效的读入方式。
对于60%的数据,N ≤ 10^5
对于100%的数据,N ≤ 10^6
数据规模非常大,请使用高效的读入方式。
做法:强行选定一个根,然后求出每个节点size的大小,当新子树大小确定时,只有一种方案,所以我们可以枚举新子树大小k,当所有节点中size值是k的倍数的节点数为n/k时,方案合法。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define N 1000007 5 using namespace std; 6 int n,tot,list[N],size[N],fa[N],b[N],ans,ls[N]; 7 struct edge{ 8 int to,next; 9 }e[N*2]; 10 bool v[N]; 11 12 inline int Read(){ 13 int s=0; 14 char ch=getchar(); 15 for(;ch<‘0‘||ch>‘9‘;ch=getchar()); 16 for(;ch>=‘0‘&&ch<=‘9‘;s=s*10+ch-‘0‘,ch=getchar()); 17 return s; 18 } 19 20 inline void Add(int x,int y){ 21 e[++tot].to=y; 22 e[tot].next=ls[x]; 23 ls[x]=tot; 24 } 25 26 void Init(){ 27 n=Read(); 28 for (int i=1;i<n;i++){ 29 int x=Read(),y=Read(); 30 Add(x,y),Add(y,x); 31 } 32 } 33 34 void Bfs(){ 35 int h=0,t=0; 36 list[++t]=1; 37 v[1]=1; 38 for(;h<t;){ 39 h++; 40 int now=list[h]; 41 for (int i=ls[now];i;i=e[i].next){ 42 if (v[e[i].to]) continue; 43 fa[e[i].to]=now; 44 list[++t]=e[i].to; 45 v[e[i].to]=1; 46 } 47 } 48 } 49 50 void Calc_son(){ 51 for (int i=1;i<=n;i++) size[i]=1; 52 for (int i=n;i>=1;i--) size[fa[list[i]]]+=size[list[i]]; 53 for (int i=1;i<=n;i++) b[size[i]]++; 54 } 55 56 int main(){ 57 Init(); 58 Bfs(); 59 Calc_son(); 60 for (int i=1;i<=n;i++){ 61 if (n%i) continue; 62 int k=0; 63 for (int j=1;j<=n/i;j++) 64 k+=b[i*j]; 65 if (k==n/i) ans++; 66 } 67 printf("%d",ans); 68 }
以上是关于JZOJ 4757. 树上摩托的主要内容,如果未能解决你的问题,请参考以下文章