题目描述

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的更多相关文章

  1. 【动态规划】cf1034C. Region Separation

    质因数分解套路的复杂度分析的动态规划 题目大意 有一颗$n$个节点有点权的树,初始整棵树为$1$号区域,要求满足下列规则: 除非$i$是最后一个等级,否则每一个$i$级区域都要被分成至少两个$i+1$ ...

  2. Codeforces Round #511 (Div. 1) C. Region Separation(dp + 数论)

    题意 一棵 \(n\) 个点的树,每个点有权值 \(a_i\) .你想砍树. 你可以砍任意次,每次你选择一些边断开,需要满足砍完后每个连通块的权值和是相等的.求有多少种砍树方案. \(n \le 10 ...

  3. 2018.9.21 Codeforces Round #511(Div.2)

    只写了AB,甚至还WA了一次A题,暴露了蒟蒻的本质=.= 感觉考的时候有好多正确或和正解有关的思路,但是就想不出具体的解法或者想的不够深(长)(怕不是过于鶸) 话说CF的E题怎么都这么清奇=.= A. ...

  4. [CF]Round511

    这场比赛我及时的参加了,但是打的时候状态实在是太烂了,只做出来了Div2的AB题. A Little C loves 3 I 直接构造就行. B Cover Points 应该很容易就看出来这个等腰三 ...

  5. Android 2D Graphics学习 Region和Canvas裁剪

    1.首先介绍Region类 Region,中文意思即区域的意思,它表示的是canvas图层上的某一块封闭的区域. /**构造方法*/ public Region()  //创建一个空的区域 publi ...

  6. #region Json转DataTable

    #region  Json转DataTable        private DataTable Json2Dtb(string json)        {            JavaScrip ...

  7. 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 ...

  8. C++中类似C# region的功能

    使用#pragma region和#pragma endregion关键字,来定义可以展开和收缩的代码区域的开头和结尾, 可以把这些代码行收缩为一行,以后要查看其细节时,可以再次展开它. 例如: // ...

  9. bdb log为什么 有 region buffer 和 log cursor buf

    对bdb log来说, 在共享内存中 有一块 buffer, 同时每一个 log cursor 都自带一个 malloc的buf. why? 我认为: region buffer存的是log最末尾, ...

  10. iOS-地图报错超出了经纬度范围Invalid Region

    做地图定位的时候,使用一下代码 // 经纬度 CLLocationDegrees latitude = [storeDict[@"lat"] doubleValue]; CLLoc ...

随机推荐

  1. AI绘图开源工具Stable Diffusion WebUI前端API对接

    背景 本文主要介绍 AI 绘图开源工具 Stable Diffusion WebUI 的 API 开启和基本调用方法,通过本文的阅读,你将了解到 stable-diffusion-webui 的基本介 ...

  2. iOS发送探针日志到日志系统的简单实现

    通过参考Testin的SDK实现方式,我们大致可以确定他们背后的实现方式: 首先,通过加载Testin的SDK,然后收集各种七七八八的数据,再通过socket发送数据到云端. 云端我们已经有了,就是h ...

  3. pandas常用的数据类型,(serises和dataform)

  4. 【效率提升】maven 转 gradle 实战

    一.灵魂三问 1.gradle 是什么? 一个打包工具, 是一个开源构建自动化工具,足够灵活,可以构建几乎任何类型的软件,高性能.可扩展.能洞察等.其中洞察,可以用于分析构建过程中数据,提供分析参考, ...

  5. 使用mtrace追踪JVM堆外内存泄露

    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明. 简介 在上篇文章中,介绍了使用tcmalloc或jemalloc定位native内存泄露的方法,但使用这个方法相 ...

  6. Codechef - Longest AND Subarray(位运算)

    题目大意   给定一个正整数N,其序列为[1, 2, 3, ..., N],找到一个长度最大的连续子列,使得其所有元素取与运算的结果为正(最终输出只需要输出最大长度即可). 思路   刚开始可能并不好 ...

  7. VS Code代码提示( AcWing算法模板,C++实现)

    算法模板提取于AcWing上的代码提示 作者:yxc 链接:https://www.acwing.com/file_system/file/content/whole/index/content/21 ...

  8. MySQL系列之MyCat——架构图、准备、安装、配置文件、垂直分表、MyCAT核心特性——分片(水平拆分)、范围分片、枚举分片、Mycat全局表、E-R分片

    文章目录 1. MyCAT基础架构图 2. MyCAT基础架构准备 2.1 环境准备: 2.2 删除历史环境: 2.3 创建相关目录初始化数据 2.4 准备配置文件和启动脚本 2.5 修改权限,启动多 ...

  9. python第6章code

    01条件判断语句 # 条件判断语句(if语句)# 语法:if 条件表达式 : # 代码块# 执行的流程:if语句在执行时,会先对条件表达式进行求值判断,# 如果为True,则执行if后的语句# 如果为 ...

  10. 关于STM32F407ZGT6的USB损坏后使用ST-Link和USART1实现串口功能

    开发板:STM32F407ZGT6: 目标:想使用软件"串口调试助手" 情况:开发板上的USB_UART口所在器件损坏或者直接没有: 解决办法:查看该开发板的原理图,可得:串口1的 ...