[CF1034C] Region Separation
题目描述
There are $ n $ cities in the Kingdom of Autumn, numbered from $ 1 $ to $ n $ . People can travel between any two cities using $ n-1 $ two-directional roads.
This year, the government decides to separate the kingdom. There will be regions of different levels. The whole kingdom will be the region of level $ 1 $ . Each region of $ i $ -th level should be separated into several (at least two) regions of $ i+1 $ -th level, unless $ i $ -th level is the last level. Each city should belong to exactly one region of each level and for any two cities in the same region, it should be possible to travel between them passing the cities in the same region only.
According to research, for each city $ i $ , there is a value $ a_i $ , which describes the importance of this city. All regions of the same level should have an equal sum of city importances.
Your task is to find how many plans there are to determine the separation of the regions that all the conditions are satisfied. Two plans are considered different if and only if their numbers of levels are different or there exist two cities in the same region of one level in one plan but in different regions of this level in the other plan. Since the answer may be very large, output it modulo $ 10^9+7 $ .
输入格式
The first line contains one integer $ n $ ( $ 1 \leq n \leq 10^6 $ ) — the number of the cities.
The second line contains $ n $ integers, the $ i $ -th of which is $ a_i $ ( $ 1 \leq a_i \leq 10^9 $ ) — the value of each city.
The third line contains $ n-1 $ integers, $ p_1, p_2, \ldots, p_{n-1} $ ; $ p_i $ ( $ p_i \leq i $ ) describes a road between cities $ p_i $ and $ i+1 $ .
题解
设 \(s=\sum\limits_{i=1}^n a_i\)
设现在要把树分成 \(i\) 份,如何判定是否可以分成 \(i\) 份呢?首先一定要满足 \(i|s\)。钦定树根为 1,定义 \(b_i\) 为 \(i\) 的子树的 \(a\) 的和。那么结论是如果存在至少(其实至多也是) \(i\) 个 \(b_i\) 满足 \(\frac{s}{i}|b_i\)。很明显,一种方案中,一个连通块的点权和等于一个 \(b_i\) 减去若干个 \(b_j\),然后他们如果都是 \(\frac{s}{i}\) 的倍数,那么减完后满足这个连通块也是 \(\frac{s}{i}\) 的倍数,所以满足每个连通块都是 \(\frac{s}{i}\) 的倍数。换句话说,如果 \(\frac{s}{i}|b_i\),那么就把 \(i\) 和父亲的连边断去,就是一个构造。
然而我们如何统计树上有多少个 \(b_j\) 满足 \(\frac{s}{i}|b_j\) 呢?暴力是 \(O(n^2)\)。同时有一个性质是 \(i\le n\),在这里做手脚,把条件转化为 \(i\) 有关的。如果 \(\frac{s}{i}|b_j\),同时 \(\frac{s}{i}|s\),所以 \(\frac{s}{i}|\gcd(b_j,s)\)。定义 \(k=\tfrac{\gcd(b_j,s)}{\frac{s}{i}}\),\(\frac{ks}{i}=\gcd(b_j,s),k\tfrac{s}{\gcd(b_j,s)}=i,\tfrac{s}{\gcd(b_j,s)}|i\)
很成功转成了 \(i\) 的条件,那么就可以直接一个筛法统计了。统计完后要计算方案数,如果可以分成 \(i\) 份,然后枚举上一次是分成几份后再分成这样的,那么 \(dp_i=1+\sum\limits_{j|i}dp_j\)。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+5,P=998244353;
int f[N],g[N],n,hd[N],e_num,ret;
LL a[N],s,ans,c[N];
struct edge{
int v,nxt;
}e[N<<1];
void add_edge(int u,int v)
{
e[++e_num]=(edge){v,hd[u]};
hd[u]=e_num;
}
LL gcd(LL x,LL y)
{
if(!y)
return x;
return gcd(y,x%y);
}
void dfs(int x,int y)
{
for(int i=hd[x];i;i=e[i].nxt)
if(e[i].v!=y)
dfs(e[i].v,x),a[x]+=a[e[i].v];
LL k=s/gcd(s,a[x]);
if(k<=n)
c[k]++;
}
int main()
{
freopen("xiongaktenioi.in","r",stdin);
freopen("xiongaktenioi.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",a+i),s+=a[i];
for(int i=2,x;i<=n;i++)
scanf("%d",&x),add_edge(x,i);
// printf("qzmakioi") ;
dfs(1,0);
// printf("qzmakioi") ;
for(int i=n-1;i>=1;i--)
for(int j=2;j*i<=n;j++)
c[j*i]+=c[i];
g[1]=1;
// printf("qzmakioi") ;
for(int i=1;i<=n;i++)
{
if(s%i==0&&c[i]==i)
{
(ret+=g[i])%=P;
for(int k=2;k*i<=n;k++)
(g[k*i]+=g[i])%=P;
}
}
printf("%d",ret);
}
[CF1034C] Region Separation的更多相关文章
- 【动态规划】cf1034C. Region Separation
质因数分解套路的复杂度分析的动态规划 题目大意 有一颗$n$个节点有点权的树,初始整棵树为$1$号区域,要求满足下列规则: 除非$i$是最后一个等级,否则每一个$i$级区域都要被分成至少两个$i+1$ ...
- Codeforces Round #511 (Div. 1) C. Region Separation(dp + 数论)
题意 一棵 \(n\) 个点的树,每个点有权值 \(a_i\) .你想砍树. 你可以砍任意次,每次你选择一些边断开,需要满足砍完后每个连通块的权值和是相等的.求有多少种砍树方案. \(n \le 10 ...
- 2018.9.21 Codeforces Round #511(Div.2)
只写了AB,甚至还WA了一次A题,暴露了蒟蒻的本质=.= 感觉考的时候有好多正确或和正解有关的思路,但是就想不出具体的解法或者想的不够深(长)(怕不是过于鶸) 话说CF的E题怎么都这么清奇=.= A. ...
- [CF]Round511
这场比赛我及时的参加了,但是打的时候状态实在是太烂了,只做出来了Div2的AB题. A Little C loves 3 I 直接构造就行. B Cover Points 应该很容易就看出来这个等腰三 ...
- Android 2D Graphics学习 Region和Canvas裁剪
1.首先介绍Region类 Region,中文意思即区域的意思,它表示的是canvas图层上的某一块封闭的区域. /**构造方法*/ public Region() //创建一个空的区域 publi ...
- #region Json转DataTable
#region Json转DataTable private DataTable Json2Dtb(string json) { JavaScrip ...
- CVPR 2011 Global contrast based salient region detection
Two salient region detection methods are proposed in this paper: HC AND RC HC: Histogram based contr ...
- C++中类似C# region的功能
使用#pragma region和#pragma endregion关键字,来定义可以展开和收缩的代码区域的开头和结尾, 可以把这些代码行收缩为一行,以后要查看其细节时,可以再次展开它. 例如: // ...
- bdb log为什么 有 region buffer 和 log cursor buf
对bdb log来说, 在共享内存中 有一块 buffer, 同时每一个 log cursor 都自带一个 malloc的buf. why? 我认为: region buffer存的是log最末尾, ...
- iOS-地图报错超出了经纬度范围Invalid Region
做地图定位的时候,使用一下代码 // 经纬度 CLLocationDegrees latitude = [storeDict[@"lat"] doubleValue]; CLLoc ...
随机推荐
- [ABC305D] Sleep Log题解
题目大意 给 \(N\) 个时刻: 当 \(i\) 为奇数时,\(A_i\) 表示刚刚起床的时刻. 当 \(i\) 为偶数时,\(A_i\) 表示开始睡觉的时刻. 有 \(Q\) 次询问,每次求在 \ ...
- K8S集群中使用JD KMS服务对敏感数据安全加密
基本概念 KMS,Key Management Service,即密钥管理服务,在K8S集群中,以驱动和插件的形式启用对Secret,Configmap进行加密.以保护敏感数据, 驱动和插件需要使用者 ...
- ImGui界面优化:使用图标字体、隐藏主窗口标题栏
目录 使用图标字体 扩展:内存加载字体 隐藏主窗口标题栏 增加程序退出 改进HideTabBar 窗口最大化 总结 本文主要介绍ImGui应用中的一些界面优化方法,如果是第一次使用ImGui推荐从上一 ...
- shopee的前景以及商用API(代码封装)
Shopee平台是东南亚和台湾地区最具代表性的电商平台之一,在过去几年里取得了巨大的成功.以下是Shopee平台的发展前景: 电商市场的快速增长:东南亚和台湾地区是人口众多.市场潜力巨大的区域,电商市 ...
- datetime去除时分秒
datetime.datetime.now().replace(microsecond=0)
- PanGu-Coder2:从排序中学习,激发大模型潜力
本文分享自华为云社区<PanGu-Coder2:从排序中学习,激发大模型潜力>,作者: 华为云软件分析Lab . 2022年7月,华为云PaaS技术创新Lab联合华为诺亚方舟语音语义实验室 ...
- mount时候遇到写保护,将以只读方式挂载
mount时候遇到写保护,将以只读方式挂载 遇到 mount: 未知的文件系统类型"(null)" [root@localhost ~]# mount /dev/sdb /mnt/ ...
- oracle多账套(用户)引用同一个账套的表或视图数据
1.赋权限访问nbjf账套权限给到其他账套用户. grant select on nbjf.receivables to gzjf,hfjf,hfjy; 2.分别登陆 gzjf,hfjf,hfjy账套 ...
- snowboy 无法 install
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple snowboy Looking in indexes: https://pypi.tun ...
- frida动态插桩初探
前言 近期碰到了分析app的需求,就学习了一下 frida的动态插桩技术.frida是一款轻量级HOOK框架,可用于多平台上,例如android.windows.ios等.frida分为两部分,服务端 ...