[莫反] [点分治] CF990G GCD Counting

posted on 2024-03-27 13:31:51 | under | source

听老师说可以直接莫反?试试看。

尝试单独分析每个询问 \(d\)。定义 \(S(i,j)\) 表示 \(i\to j\) 简单路径的 \(\gcd\) 之和,那问的就是 \(\sum\limits_i \sum\limits_j [S(i,j)=d]\)

开始推式子:

\(=\sum\limits_i \sum\limits_j [\frac{S(i,j)}{d}=1]\)

\(=\sum\limits_i \sum\limits_j \sum\limits_{pd\mid S(i,j)}\mu(p)\)

套路地提出乘积项:

\(=\sum\limits_{d\mid T} \mu(\frac Td)\sum\limits_i\sum\limits_j [T\mid S(i,j)]\)

定义 \(H(T)=\sum\limits_i\sum\limits_j [T\mid S(i,j)]\)

\(=\sum\limits_{d\mid T} H(T)\mu(\frac Td)\)

那么每次询问枚举 \(T\) 即可,现在地问题转化为 \(H(T)\) 怎么求。

显然 \(T\mid S(i,j)\) 等价于 \(T\mid a_k\),其中 \(k\)\(i\to j\) 简单路径上的点。于是进行 \(\rm dfs\),每次枚举当前点权的约数,暴力合并信息即可。

\(A\) 是点权值域。对每个因数单独建树,在新的树上统计,复杂度 \(O(n\sqrt A)\)

总复杂度:\(O(n\sqrt A + A\log A)\)

代码

其实没必要真的建树的说。

然后注意下不要把所有变量赋为 long long,否则会爆内存。

#include<bits/stdc++.h>
using namespace std;

#define LL long long
const int N = 2e5 + 5;
int pc, prime[N], f[N], mu[N], u, v;
int n, vis[N], a[N];
LL h[N], cnt;
vector<int> d[N], to[N];

inline void init(){
	f[1] = mu[1] = 1;
	for(int i = 2; i < N; ++i){
		if(!f[i]) {prime[++pc] = i, mu[i] = -1;}
		for(int j = 1; j <= pc && i * prime[j] < N; ++j){
			f[i * prime[j]] = 1, mu[i * prime[j]] = i % prime[j] ? -mu[i] : 0;
			if(i % prime[j] == 0) break;
		}
	}
}
inline void dfs(int u, int fa, int d){
	++cnt, vis[u] = 1;
	for(auto v : to[u])
		if(!vis[v] && a[v] % d == 0) dfs(v, u, d);
}
signed main(){
	init();
	cin >> n;
	for(int i = 1; i <= n; ++i){
		scanf("%d", &a[i]);
		for(int j = 1; j * j <= a[i]; ++j)
			if(a[i] % j == 0){
				d[j].push_back(i);
				if(j * j != a[i]) d[a[i] / j].push_back(i);
			}
	}
	for(int i = 1; i < n; ++i) scanf("%d%d", &u, &v), to[u].push_back(v), to[v].push_back(u);
	for(int i = 1; i < N; ++i){
		for(auto j : d[i]) 
			if(!vis[j]) 
				cnt = 0, dfs(j, 0, i), h[i] += cnt * (cnt - 1) / 2 + cnt;
		for(auto j : d[i]) vis[j] = 0;
	}
	for(int i = 1; i < N; ++i){
		LL res = 0;
		for(int j = i; j < N; j += i) res += h[j] * mu[j / i];
		if(res) printf("%d %lld\n", i, res);
	}
	return 0;
}

posted @ 2026-01-12 20:17  Zwi  阅读(3)  评论(0)    收藏  举报