bzoj 4401: 块的计数

根据块状树的那堆理论可以发现,对于某种块大小,可行的分法只有一种

如果一个点能被当成块顶,仅当其子树大小是块大小的倍数

于是枚举块的大小\(i\),当可行的块顶个数大于等于\(n / i\)时,就可以构造出可行的分法了

时间复杂度 \(O(\sum_{d|n}d)\)

#include <bits/stdc++.h>
#define N 2010000
using namespace std;
int n;
int lt[N], bi[N], nt[N], tl;
int si[N], ai[N];
void dfs(int t, int f)
{
    si[t] = 1;
    for (int i = lt[t]; i; i = nt[i])
        if (bi[i] != f)
            dfs(bi[i], t), si[t] += si[bi[i]];
    ai[si[t]] ++;
}
int ans;
int main()
{
    scanf("%d", &n);
    for (int i = 1; i < n; ++ i)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        nt[++ tl] = lt[x]; lt[x] = tl; bi[tl] = y;
        nt[++ tl] = lt[y]; lt[y] = tl; bi[tl] = x;
    }
    dfs(1, 0);
    for (int i = 1; i <= n; ++ i)
        if (n % i == 0)
        {
            int cnt = 0;
            for (int j = i; j <= n; j += i)
                cnt += ai[j];
            if (cnt >= n / i) ans ++;
        }
    printf("%d", ans);
}
时间: 2024-10-17 09:16:10

bzoj 4401: 块的计数的相关文章

bzoj 4401 块的计数 思想+模拟+贪心

块的计数 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 455  Solved: 261[Submit][Status][Discuss] Description 小Y最近从同学那里听说了一个十分牛B的高级数据结构——块状树.听说这种数据结构能在sqrt(N)的时间内维护树上的各种信息,十分的高效.当然,无聊的小Y对这种事情毫无兴趣,只是对把树分块这个操作感到十分好奇.他想,假如能把一棵树分成几块,使得每个块中的点数都相同该有多优美啊!小Y很想知

BZOJ 2111 Perm 排列计数(满二叉树)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2111 题意:求1到n有多少种排列满足:A[i]>A[i/2](2<=i<=n). 思路:形式类似二叉树.建模之后其实就是n个节点的不同的满二叉树有多少种?用f[i]表示i个节点的满二叉树个数,则f[n]=f[L]*f[R]*C(n-1,L).其中L和R对于确定的n来说是确定的.比如n=10时,左右子树分别有6.3个点. i64 a[N],n,p,f[N]; void init(

块奖励计数及其状态平衡

一.EOS的奖励制度??对记账节点的经济激励机制是区块链项目不可缺少的重要组成部分,EOS则是通过增发的方式来给予节点奖励,支付其工资.每年增发的EOS比率为5%左右,按照总供应量10亿来计算,就是五千万EOS. 通胀的EOS用途: ??如上图,通胀的EOS币先发行到系统账户eosio中,其中的20%, 用于节点奖励:另外80%,用于EOS基金池,会在未来用于社区福利应用或者对EOS系统有所帮助的项目.该部分资金存入eosio.saving系统账户中.??EOS节点分为两类:出块节点(Block

BZOJ 4517: [Sdoi2016]排列计数 错排+逆元

4517: [Sdoi2016]排列计数 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m 个数是稳定的 满足条件的序列可能很多,序列数对 10^9+7 取模. Input 第一行一个数 T,表示有 T 组数据. 接下来 T 行,每行两个整数 n.m. T=500000,n≤1000000,m≤1000000 Output 输出 T 行,每行一个数,表示

BZOJ 1016 [JSOI2008]最小生成树计数 ——Matrix-Tree定理

考虑从小往大加边,然后把所有联通块的生成树个数计算出来. 然后把他们缩成一个点,继续添加下一组. 最后乘法原理即可. 写起来很恶心 #include <queue> #include <cmath> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace s

[BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】

题目链接:BZOJ - 1016 题目分析 最小生成树的两个性质: 同一个图的最小生成树,满足: 1)同一种权值的边的个数相等 2)用Kruscal按照从小到大,处理完某一种权值的所有边后,图的连通性相等 这样,先做一次Kruscal求出每种权值的边的条数,再按照权值从小到大,对每种边进行 DFS, 求出这种权值的边有几种选法. 最后根据乘法原理将各种边的选法数乘起来就可以了. 特别注意:在DFS中为了在向下DFS之后消除决策影响,恢复f[]数组之前的状态,在DFS中调用的Find()函数不能路

数学(错排):BZOJ 4517: [Sdoi2016]排列计数

4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 693  Solved: 434[Submit][Status][Discuss] Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m 个数是稳定的 满足条件的序列可能很多,序列数对 10^9+7 取模. Input 第

bzoj 1004 Cards 组合计数

这道题考察的是组合计数(用Burnside,当然也可以认为是Polya的变形,毕竟Polya是Burnside推导出来的). 这一类问题的本质是计算置换群(A,P)中不动点个数!(所谓不动点,是一个二元组(a,p),a∈A,p∈P ,使得p(a)=a,即a在置换p的作用后还是a). Polya定理其实就是告诉了我们一类问题的不动点数的计算方法. 对于Burnside定理的考察,我见过的有以下几种形式(但归根结底还是计算不动点数): 1.限制a(a∈A)的特点,本题即是如此(限制了各颜色个数,可以

BZOJ 4517: [Sdoi2016]排列计数

4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 911  Solved: 566[Submit][Status][Discuss] Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m 个数是稳定的 满足条件的序列可能很多,序列数对 10^9+7 取模. Input 第