题解——count(树上切割)
今天考试T1,和我之前写的一篇叫做草莓的题解有点像
题面
Description
求一共有多少种方案可以把一棵树分成大小相同的几块。
Input
第一行一个数N,表示数的大小。
第二行至第N行,每行两个数x,y表示x和y之间有一条边。
Output
一行,表示方案数。
Sample Input
6
1 2
2 3
2 4
4 5
5 6
Sample Output
3
思路
我们考虑,如果数 Ai 能够满足将一棵树切割为若干大小相同的块,那么首先 Ai 必须是 N 的因数。(在1e6的数据内,最大的因数个数是一个较小的3位数)。然后,像草莓那道题一样,枚举每个因数,只要存在能将一个子树大小刚为因数的,我们就将这个子树减去。如果子树大小超了,那么肯定无法减去。
题解传送门:题解——草莓`
AC code: 我写的相当简洁
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1000005 ;
inline int read(){
int s=0 ;char g=getchar() ; while( g>'9'||g<'0')g=getchar() ;
while( g>='0'&&g<='9')s=s*10+g-'0',g=getchar() ; return s ;
}
int N , size[ MAXN ] , head[ MAXN ] ,to[ MAXN*2 ] , nex[ MAXN*2 ] , ans = 0 , tot = 1 ;
bool key ;
void add( int x , int y ){
to[ ++tot ] = y , nex[ tot ] = head[ x ] , head[ x ] = tot ;
}
void dfs( int u , int fa , int val ){
if( !key )return ;//剪枝
size[ u ] = 1 ;//本身
for( register int i = head[ u ] ; i ; i = nex[ i ] ){
if( to[ i ] == fa )continue ;
dfs( to[ i ] , u , val ) ;
size[ u ] += size[ to[ i ] ] ;
}
if( size[ u ] == val )size[ u ] = 0 ;
if( size[ u ] > val ){key = false ; return ;}
}
int main(){
N = read() ; int m1 , m2 ;
for( register int i = 1 ; i < N ; ++i ){
m1 = read() , m2 =read() ;
add( m1 , m2 ) , add( m2 ,m1 ) ;
}
ans = 1 ; // 1
for( register int i = 2 ; i <= N ; ++i )
if( !( N%i ) ){
key = true ;
dfs( 1 , 1 , i ) ;
if( key ){
ans++ ;
}
}
cout<<ans ;
return 0 ;
}
}