zoukankan      html  css  js  c++  java
  • bzoj 4401 块的计数 思想+模拟+贪心

    块的计数

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 455  Solved: 261
    [Submit][Status][Discuss]

    Description

    小Y最近从同学那里听说了一个十分牛B的高级数据结构——块状树。听说这种数据结构能在sqrt(N)的时间内维护树上的各种信息,十分的高效。当然,无聊的小Y对这种事情毫无兴趣,只是对把树分块这个操作感到十分好奇。他想,假如能把一棵树分成几块,使得每个块中的点数都相同该有多优美啊!小Y很想知道,能有几种分割方法使得一棵树变得优美。小Y每次会画出一棵树,但由于手速太快,有时候小Y画出来的树会异常地庞大,令小Y感到十分的苦恼。但是小Y实在是太想知道答案了,于是他找到了你,一个天才的程序员,来帮助他完成这件事。

    Input

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

    Output

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

    Sample Input

    6
    1 2
    2 3
    2 4
    4 5
    5 6

    Sample Output

    3

    HINT

    100%的数据满足N<=1000000。

    Source

     首先随便选一个根进行dfs得到size[x]表示以x为根节点的子树的大小。然后我们假设答案为t,需要判断t是否可行。首先显然需要t|n。

    显然每一个块有且仅有一个根,定义为这个块的最高点。然后我们发现一个点x是块的根的必要条件是t|size[x]!这个是显然的。然后我

    们统计有多少个size[x]被t整除,如果与n/t相同则合法,否则一定小于n/t,因此一定不合法。

     1 #include<cstring>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstdio>
     6 
     7 #define N 1000007
     8 #define ll long long
     9 
    10 using namespace std;
    11 inline int read()
    12 {
    13     int x=0,f=1;char ch=getchar();
    14     while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
    15     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    16     return x*f;
    17 }
    18 
    19 int n,ans;
    20 int Head[N],ret[N<<1],Next[N<<1],tot;
    21 int size[N],st[N];
    22 
    23 inline void ins(int u,int v)
    24 {
    25     ret[++tot]=v;
    26     Next[tot]=Head[u];
    27     Head[u]=tot;
    28 }
    29 void dfs(int u,int f)
    30 {
    31     size[u]=1;
    32     for (int i=Head[u];i;i=Next[i])
    33     {
    34         if (ret[i]==f) continue;
    35         dfs(ret[i],u);
    36         size[u]+=size[ret[i]];
    37     }
    38     st[size[u]]++;
    39 }
    40 int main()
    41 {
    42     n=read();
    43     for (int i=1;i<n;i++)
    44     {
    45         int u=read(),v=read();
    46         ins(u,v);ins(v,u);
    47     }
    48     dfs(1,0);
    49     for (int i=1;i<=n;i++)
    50         if (n%i==0)
    51         {
    52             int sum=0;
    53             for (int j=i;j<=n;j+=i)
    54                 sum+=st[j];
    55             if (sum==n/i) ans++;
    56         }
    57     printf("%d
    ",ans);
    58 }
  • 相关阅读:
    Search a 2D Matrix leetcode java
    Sqrt(int x) leetcode java
    Search for a Range leetcode java
    php获取客户端公网ip代码
    ddns+ros(routeros)+centos7.6+nginx+php+dnspod
    limits.conf文件修改注意事项,限制文件描述符数和进程数
    阿里云本地存储网关的一些特点和注意事项
    ROS根据访问不同的网址,走不同的路由策略的脚本
    漫威所有电影的 按时间线的观影顺序
    sklearn—特征工程
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8168797.html
Copyright © 2011-2022 走看看