• bzoj4401: 块的计数


    首先,块的大小确定的话,可以发现方案最多只有1种

    然后就可以O(nsqrt(n))搞,不过会TLE

    接着我们又发现,一个节点可以作一个块的根,当且仅当该节点的size能被块的大小整除

    然后就可以O(nlogn)搞了

    详见代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    #define N 1000006
    #define M 2000006
    
    using namespace std;
    inline int read(){
    	int ret=0;char ch=getchar();
    	while (ch<'0' || ch>'9') ch=getchar();
    	while ('0'<=ch && ch<='9'){
    		ret=ret*10-48+ch;
    		ch=getchar();
    	}
    	return ret;
    }
    
    struct edge{
    	int adj,next;
    	edge(){}
    	edge(int _adj,int _next):adj(_adj),next(_next){}
    } e[M];
    int n,g[N],m;
    void AddEdge(int u,int v){
    	e[++m]=edge(v,g[u]);g[u]=m;
    	e[++m]=edge(u,g[v]);g[v]=m;
    }
    
    int cnt[N];
    int size[N];
    bool vis[N];
    void dfs(int u){
    	vis[u]=1;size[u]=1;
    	for (int i=g[u];i;i=e[i].next){
    		int v=e[i].adj;
    		if (vis[v]) continue;
    		dfs(v);
    		size[u]+=size[v];
    	}
    	++cnt[size[u]];
    }
    
    int main(){
    	n=read();
    	memset(g,0,sizeof(g));m=1;
    	for (int i=1;i<n;++i) AddEdge(read(),read());
    	memset(cnt,0,sizeof(cnt));
    	memset(vis,0,sizeof(vis));
    	dfs(1);
    	int ans=0;
    	for (int i=1;i<=n;++i){
    		for (int j=2;i*j<=n;++j)
    			cnt[i]+=cnt[i*j];
    		if (i*cnt[i]==n) ++ans;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

      

  • 相关阅读:
    K均值算法
    4.K均值算法应用
    js实现点击不同按钮切换内容
    vue框架中的日期组件转换为yyymmdd格式
    sessionStorage和localStorage的使用方法
    vue中使用axios
    js中的原型对象链
    web端常见测试点
    软件测试手工测试
    前端面试题vue部分
  • 原文地址:https://www.cnblogs.com/wangyurzee7/p/5129652.html
Copyright © 2020-2023  润新知