zoukankan      html  css  js  c++  java
  • 【bzoj4401】块的计数 结论题

    题目描述

    给出一棵n个点的树,求有多少个si使得整棵树可以分为n/si个连通块。

    输入

    第一行一个正整数N,表示这棵树的结点总数,接下来N-1行,每行两个数字X,Y表示编号为X的结点与编号为Y的结点相连。结点编号的范围为1-N且编号两两不同。

    输出

    一行一个整数Ans,表示所求的方案数。

    样例输入

    6
    1 2
    2 3
    2 4
    4 5
    5 6

    样例输出

    3


    题解

    结论题

    结论:k可行当且仅当子树大小是k的倍数的节点数有n/k个。

    这结论好像挺显然的(只要你能想出来。。。)

    然后就做完了。。。先预处理出每个节点的size,对size维护桶,枚举n的约数,再枚举它的倍数求和统计即可。

    时间复杂度为 $O(sumlimits_{k|n}frac nk=sumlimits_{k|n}k=nloglog n)$ 

    #include <cstdio>
    #include <cctype>
    #define N 1000010
    int head[N] , to[N << 1] , next[N << 1] , cnt , si[N] , v[N];
    inline void add(int x , int y)
    {
    	to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;
    }
    void dfs(int x , int fa)
    {
    	int i;
    	si[x] = 1;
    	for(i = head[x] ; i ; i = next[i])
    		if(to[i] != fa)
    			dfs(to[i] , x) , si[x] += si[to[i]];
    	v[si[x]] ++ ;
    }
    inline char nc()
    {
    	static char buf[100000] , *p1 , *p2;
    	return p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 100000 , stdin) , p1 == p2) ? EOF : *p1 ++ ;
    }
    inline int read()
    {
    	int ret = 0; char ch = nc();
    	while(!isdigit(ch)) ch = nc();
    	while(isdigit(ch)) ret = ((ret + (ret << 2)) << 1) + (ch ^ '0') , ch = nc();
    	return ret;
    }
    int main()
    {
    	int n = read() , i , x , y , ans = 0;
    	for(i = 1 ; i < n ; i ++ ) x = read() , y = read() , add(x , y) , add(y , x);
    	dfs(1 , 0);
    	for(i = 1 ; i <= n ; i ++ )
    	{
    		if(!(n % i))
    		{
    			for(x = 0 , y = i ; y <= n ; y += i) x += v[y];
    			if(x == n / i) ans ++ ;
    		}
    	}
    	printf("%d
    " , ans);
    	return 0;
    }
    

     

  • 相关阅读:
    DLL文件是什么?
    regsvr32的作用是什么?
    win10 解决.net framework 3.5 (安装报错 0x80240438)
    git 常用命令
    Wine使用初体验
    Windows 桌面快捷方式图标变白的问题
    WSL使用初体验/WIN10下安装ubuntu20.04
    Windows 重新安装Microsoft Store/用户无权进入WindowsApps文件夹
    linux命令
    linux命令
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/8072101.html
Copyright © 2011-2022 走看看