首页 > 其他分享 >题解 CF1034C【Region Separation】/ SS221116D【Xiong AK 10 IOI】

题解 CF1034C【Region Separation】/ SS221116D【Xiong AK 10 IOI】

时间:2023-10-04 14:22:23浏览次数:47  
标签:10 连通 frac gcd int 题解 LL IOI siz

很妙的性质题!全是意识流证明见过吗?

problem

每次选一个非空边集删掉,谓之曰砍树。砍树后需要满足每个连通块的点权和相同。

在一个方案中可以砍很多次树,都要满足砍树后的要求。一共有多少种合法方案呢?

\(n\leq 10^6,1\leq a_i\leq 10^9\)。

solution

假如我们将树砍成 \(k\) 个连通块,我们发掘一些性质:

  • 砍树方案唯一。证明:
    1. 这是棵树。
    2. 点权非负。
  • 记所有点权和为 \(S\),则有 \(k\) 个连通块的和为 \(S/k\)。(这变相要求了 \(k|S\))。
  • 如果再砍一刀,砍完后的 \(k'|k\),可以看作每个连通块独立。

考虑求出 \(f(k)\) 表示砍成 \(k\) 个连通块是不是可能的。

考虑一种贪心:从底向上,维护子树大小,如果碰到 \(siz_u=S/k\) 马上砍了,然后 \(u\) 到根的路径集体减 \(siz_u\)。

猜测结论:只有恰好 \(k\) 个 \(\frac{S}{k}|siz_u\) 才说 \(f(k)=true\)。

证明
  1. 每个点唯一的包含在一个连通块中。
  2. 若一个点 \(u\) 满足 \(\frac{S}{k}|siz_u\),且 \(f(k)=true\),则子树 \(u\) 必然分成了 \(siz_u/\frac{S}{k}\) 份连通块才是正确的。请记住,点权非负。
  3. 考虑点 \(u\) 在一个连通块中是吧,我们令 \(\Sigma=\frac{S}{k}\),则一个 \(siz_u\) 可以看作是包含点 \(u\) 一个 \(\Sigma\) 和其它所有儿子满足 \(\Sigma|siz_v\) 的和。
  4. 它的本质是,每一个连通块只会算一次,刚好算了 \(k\) 次。

啊这个结论很强,但我们还是不会快速求 \(f(k)\) 呢,考虑把它变成 \(\frac{S}{\gcd(S,siz_u)}|k\)。

过程

方法一

令 \(a=\frac{S}{k}\)。

显然有 \(a|siz_u,a|S\Rightarrow a|\gcd(siz_u,S)\)。

\(\therefore \frac{S}{k}|\gcd(siz_u,S)\Rightarrow \frac{S}{\gcd(S,siz_u)}|k\)。

方法二

\(\frac{S}{k}|siz_u\Rightarrow \frac{S}{siz_u}|k\)。

令 \(d=\gcd(S,siz_u)\),则分数化简 \(\frac{S/d}{siz_u/d}|k\)。

现在左边这东西不是整数,考虑整除本质 \(x\frac{S/d}{siz_u/d}=k\)。

\(\because k\in N^+,\therefore siz_u/d|x\),这样才能约分成整数。

考虑去掉 \(x\) 的这一部分,即 \(\frac{S\cdot siz_u/d}{siz_u}|k\Rightarrow \frac{S}{\gcd(S,siz_u)}|k\)。

喵喵喵,这样我们求出 \(\frac{S}{\gcd(S,siz_u)}\) 然后枚举倍数就行了。

考虑砍了很多次之后砍成 \(k\) 个连通块的方案数:\(g_k=f(k)+\sum_{j|k,j\neq k}g_j\)。

做完了。

code

点击查看代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#ifdef LOCAL
#define debug(...) fprintf(stderr,##__VA_ARGS__)
#else
#define debug(...) void(0)
#endif
typedef long long LL;
const int P=1e9+7;
void red(LL&x){x=(x%P+P)%P;}
LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);}
int n,fa[1000010];
LL f[1000010],siz[1000010],g[1000010],ans=0;
int main(){
	freopen("xiongaktenioi.out","w",stdout);
//	#ifdef LOCAL
	 	freopen("xiongaktenioi.in","r",stdin);
//	#endif
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%lld",&siz[i]);
	for(int i=2;i<=n;i++) scanf("%d",&fa[i]);
	for(int i=n;i>=2;i--) siz[fa[i]]+=siz[i];
	for(int i=1;i<=n;i++){
		LL w=siz[1]/gcd(siz[i],siz[1]);
		debug("siz[%d]=%lld,w=%lld\n",i,siz[i],w);
		for(LL j=w;j<=n;j+=w) f[j]++;
	}
	for(int i=n;i>=2;i--){
		if(f[i]==i){
			g[i]=1;
			for(int j=i+i;j<=n;j+=i) red(g[i]+=g[j]);
			red(ans+=g[i]);
			debug("g[%d]=%lld\n",i,g[i]);
		}
	}
	printf("%lld\n",ans+1);
	return 0;
}

标签:10,连通,frac,gcd,int,题解,LL,IOI,siz
From: https://www.cnblogs.com/caijianhong/p/solution-SS221116D.html

相关文章

  • 传奇团子师傅题解
    传奇团子师傅题解(模拟退火)申明:本篇题解借鉴了:https://www.luogu.com.cn/blog/SDNetFriend/solution-p7218这篇博客(主要在bitset部分)。题意:给你个矩阵,包含三种颜色,一个美丽串要求你横着或者竖着或者斜着串成一串的三个颜色有特定的顺序,求拿取最多美丽串的方案是什么。题目分......
  • 【UVA 442】Matrix Chain Multiplication 题解(栈)
    假设您必须计算一个表达式,如ABCDE,其中A、B、C、D和E是矩阵。由于矩阵乘法是关联的,所以执行乘法的顺序是任意的。然而,所需的初等乘法的数量很大程度上取决于求值顺序您可以选择。例如,设A为5010矩阵,B为1020矩阵,C为205矩阵。有两个计算ABC的不同策略,即(AB)C和A(B*C)。第一个需要1500......
  • CVE-2010-2883 学习记录(漏洞战争,启动!)
    格式分析Header:文件头,用来注明pdf文件版本号Body:主要由组成文件的对象组成,例如图片,文字Cross-regerencetable:交叉引用表,用于存放所有对象的引用、位置偏移、字节长度,用于随机访问pdf中的任意对象Trailer:文件尾,给出交叉引用表的位置(指针)和一些关键对象的信息(指针),......
  • Hadoop问题解决记(2)
     1.发现问题在对HBase集群进行压力测试过程中发现,当实际写入HBase和从HBase查询的量是平时的若干倍时(集群规模10~20台,每秒读写数据量在几十万条记录的量级),导致集群的读写出现一定程度的波动。具体如下:1)写端抛出以下异常信息:org.apache.hadoop.hbase.client.RetriesExha......
  • Hadoop问题解决记(1)
    最近在测试HBase时遇到一个非常奇怪的问题:集群有7台机器,其中1台Master,6台RegionServer。但是Master只能控制其中1台RegionServer,而无法控制其他5台RegionServer。打开master的日志文件,发现以下错误信息:2011-04-2216:37:21,242WARNorg.apache.hadoop.hbase.master.Assignment......
  • 10.4 国庆 环形dp与基环树笔记
    1.知识点环形dp环形dp的概念•环形dp与基环树在许多环形结构的问题中,我们可以在环中从某个位置把环断开,把这个环变成线性的,然后进行\(dp\)等操作。•把能通过上述操作解决的环形问题称作"可拆解的环形问题"。环形dp的两种策略•第一次在任意位置把环断开成链,按照......
  • 『题解』P9688
    题目传送门思路:设有两个颜色\(x_1x_2\),两端分别为\(l_1\)\(r_1\),\(l_2\)\(r_2\)。通过观察可以发现,若满足\(x_1<x_2\)且\(r_1>l_2\)则\(x_1x_2\)一定是单调不下降的。那么我们可以先预处理出一个颜色可以与前面的哪些颜色构成单调不下降,然后用dp求出最终答案......
  • 10.1 调试事件读取寄存器
    当读者需要获取到特定进程内的寄存器信息时,则需要在上述代码中进行完善,首先需要编写CREATE_PROCESS_DEBUG_EVENT事件,程序被首次加载进入内存时会被触发此事件,在该事件内首先我们通过lpStartAddress属性获取到当前程序的入口地址,并通过SuspendThread暂停程序的运行,当被暂停后则我没......
  • 每日总结2023/10/03(c#安装教程)
     C#,入门教程(01)——VisualStudio2022免费安装的详细图文与动画教程_visualstudio2022安装c#教程-CSDN博客......
  • 题解 Coloring Brackets
    题目链接对于括号问题,考虑区间\(dp\)。这道题的括号序列是固定的,所以直接找出每个括号对应的括号在进行转化即可。设\(f_{l,r,0/1/2,0/1/2}\)表示\(l\simr\),左括号不染色/染红色/染蓝色,右括号不染色/染红色/染蓝色的方案数。若\(l,r\)是一对匹配括号,那么f_{l,r}便可以......