hdu 5329 Question for the Leader
2015-08-03 20:04
369 查看
hdu 5329 Question for the Leader
题意:
给出一个有n个点的图,这个图是由一个基环 + 若干外向树组成,问能否把这个图分成 k个 大小为n/k 的 连通的子图,问k有多少种。
限制:
1 <= n <= 1e5
思路:
主要是一个性质:
对于一棵树,如果可以把这棵树分成大小都为k的n/k份,那子树大小是k的倍数的节点恰好有n/k个。(任意选定一个根)
详细见多校官方题解
http://blog.sina.com.cn/u/5657719201
题意:
给出一个有n个点的图,这个图是由一个基环 + 若干外向树组成,问能否把这个图分成 k个 大小为n/k 的 连通的子图,问k有多少种。
限制:
1 <= n <= 1e5
思路:
主要是一个性质:
对于一棵树,如果可以把这棵树分成大小都为k的n/k份,那子树大小是k的倍数的节点恰好有n/k个。(任意选定一个根)
详细见多校官方题解
http://blog.sina.com.cn/u/5657719201
/*hdu 5329 Question for the Leader 题意: 给出一个有n个点的图,这个图是由一个基环 + 若干外向树组成,问能否把这个图分成 k个 大小为n/k 的 连通的子图,问k有多少种。 限制: 1 <= n <= 1e5 思路: 主要是一个性质: 对于一棵树,如果可以把这棵树分成大小都为k的n/k份,那子树大小是k的倍数的节点恰好有n/k个。(任意选定一个根) 详细见多校官方题解 */ #include <iostream> #include <cstdio> #include <vector> #include <cstring> using namespace std; #define PB push_back const int N = 1e5 + 5; int a ; int cir , cir_tot; bool in_cir ; int tree_sz ; int cnt ; vector<int> G ; int fa ; void init_bcj(int n) { for(int i = 0; i <= n; ++i) fa[i] = i; } int get_fa(int x) { if(x != fa[x]) return fa[x] = get_fa(fa[x]); return x; } int dfs(int u, int fa) { tree_sz[u] = 1; for(int i = 0; i < G[u].size(); ++i) { int ch = G[u][i]; if(ch == fa || in_cir[ch]) continue; tree_sz[u] += dfs(ch, u); } return tree_sz[u]; } int sum , sum_cnt ; bool ok(int bei, int have, int n) { for(int i = 0; i < bei; ++i) sum_cnt[i] = 0; sum[0] = tree_sz[cir[0]] % bei; ++sum_cnt[sum[0]]; for(int i = 1; i < cir_tot; ++i) { sum[i] = (sum[i - 1] + tree_sz[cir[i]]) % bei; ++sum_cnt[sum[i]]; } if(sum_cnt[0] + have == n / bei) return true; int last = cir_tot - 1; for(int i = 0; i < cir_tot - 1; ++i) { --sum_cnt[sum[i]]; int tmp = sum[i]; sum[i] = (sum[last] + tree_sz[cir[i]]) % bei; ++sum_cnt[sum[i]]; if(sum_cnt[tmp] + have == n / bei) return true; last = i; } return false; } void gao(int n) { cir_tot = 0; for(int i = 1; i <= n; ++i) { G[i].PB(a[i]); G[a[i]].PB(i); int fx = get_fa(i); int fy = get_fa(a[i]); if(fx != fy) fa[fy] = fx; else if(cir_tot == 0){ cir[cir_tot++] = i; in_cir[i] = 1; } } int nxt = a[cir[0]]; while(nxt != cir[0]) { cir[cir_tot++] = nxt; in_cir[nxt] = 1; nxt = a[nxt]; } for(int i = 1; i <= n; ++i) { if(in_cir[i]) dfs(i, -1); } for(int i = 1; i <= n; ++i) if(!in_cir[i]) ++cnt[tree_sz[i]]; for(int i = 1; i <= n; ++i) { for(int j = 2 * i; j <= n; j += i) { cnt[i] += cnt[j]; } } int ans = 0; for(int i = 1; i <= n; ++i) { if(n % i) continue; if(ok(i, cnt[i], n)){ ++ans; } } printf("%d\n", ans); } void init(int n) { init_bcj(n); memset(in_cir, 0, sizeof(in_cir)); memset(tree_sz, 0, sizeof(tree_sz)); memset(cnt, 0, sizeof(cnt)); for(int i = 0; i <= n; ++i) G[i].clear(); } int main() { int n; while(scanf("%d", &n) != EOF) { init(n); for(int i = 1; i <= n; ++i){ scanf("%d", &a[i]); } gao(n); } return 0; }
相关文章推荐
- XML::Parser perl module is required for intltool错误
- Uva 11324 The Largest Clique【强连通 DAG动规 spfa】
- UVa 10534 DP LIS Wavio Sequence
- wpf鼠标捕获与控件交互——UIElement.CaptureMouse
- scala GUI界面开发
- UIRefreshControl 实现UITableView的下拉刷新
- UITableViewCell 如何获取自身高度
- UI简单页面设计
- UI类的扩展和触碰
- IOS UIWenView 调整页面字体大小
- iOS蓝牙4.0开发02-Core Bluetooth框架综述
- 提升UITableView性能-复杂页面的优化
- 第二十七篇:SOUI中控件属性查询方法
- UI中的协议使用步骤
- String StringBuffer StringBuilder比较
- iOS之自定义导航按钮UIBarButtonItem的样式
- easyUI的combox三级联动
- 56.UICollectionView的基本使用
- UITarget-Action(定义一个触碰屏幕启动功能的方法)
- hdu 1711 Number Sequence(求模式串首次出现在文本串的位置)