BZOJ4401:块的计数(乱搞)
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
1 2
2 3
2 4
4 5
5 6
Sample Output
HINT
100%的数据满足N<=1000000。
Solution
我竟然天真的以为$2e8$能跑过去直到我被最大的点卡到$10s$……
感觉也说不上什么算法,就算他是乱搞吧。
一开始洲哥给了一个$n\sqrt{n}$的写法。下一段根号做法可以不看因为我感觉我写的可能比正解还难懂……
我们先枚举当前要分的块大小$k$,再随便找一个根$DFS$一下,从下往上贪心的分,也就是够$k$个就分成一块。感性理解一下还是非常正确的……对于每个点$x$我们求出$(\sum size[son[x]]\%k)+1$,如果存在某个点的这个值大于$k$的话显然就是不合法的。其中$size[son[x]]\%k$也就是$son[x]$这颗子树里面分完了剩下的点。这个为什么是对的我就不多说了……要真想不懂的话可以直接去看下面正解做法。
其实仔细想想,确定了块大小$k$之后,那么每一块内的根的$size$肯定就是$k$的倍数。这个应该还是比较显然的,因为你是从下往上贪心来分的。那么我们直接开个桶记下$size$,对于每一个能被$n$整除的块大小$k$,统计有多少$size[x]$被$k$整除,如果与$n/k$相同则合法。复杂度应该是$O(n+\sqrt{n}logn)$
Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #define N (1000009) 5 using namespace std; 6 7 struct Edge{int to,next;}edge[N<<1]; 8 int n,ans,size[N],u,v,Keg[N]; 9 int head[N],num_edge; 10 11 inline int read() 12 { 13 int x=0; char c=getchar(); 14 while (c<'0' || c>'9') c=getchar(); 15 while (c>='0' && c<='9') x=x*10+c-'0', c=getchar(); 16 return x; 17 } 18 19 void add(int u,int v) 20 { 21 edge[++num_edge].to=v; 22 edge[num_edge].next=head[u]; 23 head[u]=num_edge; 24 } 25 26 void DFS(int x,int fa) 27 { 28 size[x]=1; 29 for (int i=head[x]; i; i=edge[i].next) 30 if (edge[i].to!=fa) 31 { 32 DFS(edge[i].to,x); 33 size[x]+=size[edge[i].to]; 34 } 35 Keg[size[x]]++; 36 } 37 38 int main() 39 { 40 n=read(); 41 for (int i=1; i<=n-1; ++i) 42 { 43 u=read(); v=read(); 44 add(u,v); add(v,u); 45 } 46 DFS(1,0); 47 for (int i=1; i<=n; ++i) 48 if (n%i==0) 49 { 50 int sum=0; 51 for (int j=1; i*j<=n; ++j) 52 sum+=Keg[i*j]; 53 ans+=(sum==n/i); 54 } 55 printf("%d\n",ans); 56 }
转载于:https://www.cnblogs.com/refun/p/10219614.html
BZOJ4401:块的计数(乱搞)相关推荐
- BZOJ4401 块的计数
传送门 分析 结论题.假设分成的每块大小为 \(k\),则分成了 \(\frac{n}{k}\) 块,也就是 \(k|n\) ,有 \(\frac{n}{k}\) 个节点可以作为每块的根节点,显然,这 ...
- BZOJ 1124 [POI2008]枪战Maf 贪心+乱搞
题意:略. 方法:贪心+乱搞. 解析: 今天做的题里面最难的了- 分连通块进行考虑. 一个连通块最多死多少呢? 一个点 -> 死一个 一个环 -> 死环上点个数-1个 一个环加上内向树 - ...
- POJ 3842 An Industrial Spy 快筛质数+STL乱搞
题目大意:n组数据,每组数据给出不超过7个数字,将这些数字排列,问能组成多少个素数. 思路:观察数据范围,7个数字,最多就是10^7个数,开一个bool就能存下那些是素数.当然最好还是线性筛,O(n) ...
- AcWing 397. 逃不掉的路(边双连通分量缩点成树 + 树链剖分乱搞)
整理的算法模板合集: ACM模板 我们知道在同一个边双连通分量中的点没有必经边(因为至少有两条分离的路径). 所以我们直接tarjan求出桥后缩点,然后求一下树上两点间的距离即可. 那么如何求树上两点 ...
- bzoj 1050: [HAOI2006]旅行comf(codevs.cn 1001 舒适的路线) 快排+并查集乱搞
没用的话:好像很久没发博客了,主要是懒太蒟找不到水题.我绝对没弃坑...^_^ 还用些话:本文为博主原创文章,若转载请注明原网址和作者. 进入正题: 先pa网址: bzoj :http://www.l ...
- BZOJ-1800 飞行棋 数学+乱搞
这道题感觉就是乱搞,O(n^4)都毫无问题 1800: [Ahoi2009]fly 飞行棋 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1172 So ...
- 【BZOJ-3578】GTY的人类基因组计划2 set + map + Hash 乱搞
3578: GTY的人类基因组计划2 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 367 Solved: 159 [Submit][Status ...
- Luogu3732 [HAOI2017] 供给侧改革 【后缀数组】【线段树】【乱搞】
题目分析: 这道题我是乱搞的,因为他说$01$串是随机的. 那么我们可以猜测能够让LCP变大的地方很少.求出后缀数组之后可能让LCP变大的地方就等价于从大到小往height里动态加点同时维护这个点左右 ...
- 【uoj#209】[UER #6]票数统计 组合数+乱搞
题目描述 一个长度为 $n$ 的序列,每个位置为 $0$ 或 $1$ 两种.现在给出 $m$ 个限制条件,第 $i$ 个限制条件给出 $x_i$ .$y_i$ ,要求至少满足以下两个条件之一: 序列的 ...
最新文章
- Openlayers中使用animate实现车辆定位导航效果(以当前车辆为中心移动)
- C++之inline函数使用总结
- 微信小程序 - 回到自己位置(map)
- 数据倾斜原理及解决方案
- android 编译 c 程序,Android上通过gcc编译普通的C程序
- swift 第五课 定义model类 和 导航栏隐藏返回标题
- mysql 加密 en_MySQL8.0 的表空间文件加密控制
- Windows 10 IoT Core 17115 for Insider 版本更新
- 【GIS导论】实验一 桌面GIS的功能与菜单操作
- python采集微信聊天信息_我用 Python 破解了微信聊天记录,自动同步微信文章
- 关于 PCB 多层板制程能力不得不说的那些事儿
- java 解析dojo_Dojo入门三种HelloWorld!
- 武汉_金山wps Java 一面 二面
- ATTck 命令执行 —— 远程动态数据交换
- Camtasia Studio 录制视频保存为camrec格式后快速导出为AVI格式
- 菜鸟学JAVA之——常用类(StringBuffer、StringBuilder、Comparable、Comparator等)
- 群晖域名解析出现错误?别慌,排查原因有步骤
- TensorFlow2 手把手教你实现自定义层
- 用户注册邮箱通知和短信通知详解(php)
- 计算机加密恢复,系统小技巧:BitLocker密钥恢复二三事