「2021集訓隊互測」Lovely Dogs

zyxawa發表於2024-07-28

對於 \(x=\prod\limits_{i=1}^m p_i^{k_i}\),由於 \(f_d(x)\) 因為 \([k_i \le d]\) 而沒有任何性質來化簡原式,考慮設 \(f(x)=\prod\limits_{i=1}^m (-1)^{k_i}[k_i \le d]\)\(g(x)=\prod\limits_{i=1}^m (-1)^{k_i}\)

那麼 \(g(x)\) 是完全積性函式且 \(f(ij)=g(i)g(j)f(ij)\),令 \(h(i)\) 表示最大的 \(t\) 滿足 \(t^{d+1} \mid i\),那麼 \(f(ij)=[h(ij)=1]=\sum\limits_{t \mid h(ij)} \mu(t)=\sum\limits_{t^{d+1}\mid ij} \mu(t)\)

考慮 dsu on tree,每次將 \(b\) 加入集合 \(S\) 的增量為 \(\sum\limits_{a\in S}f(ab)=\sum\limits_{a\in S} g(a)g(b)\sum\limits_{t^{d+1} \mid ab}\mu(t)=g(b)\sum\limits_t \mu(t) \sum\limits_{a\in S} [t^{d+1} \mid ab]g(a)=g(b)\sum\limits_t \mu(t) \sum\limits_{a\in S} [\dfrac{t^{d+1}}{\gcd(t^{d+1},a)}] g(a)=f(b)\sum\limits_{t\mid b} \mu(t) \sum\limits_{a\in S} [\dfrac{t^{d+1}}{\gcd(t^{d+1},a)}] f(a)\),注意到 \(t\) 只要列舉到 \(b\) 的因數,否則 \(a\) 裡面一定有一個 \(d+1\) 次的質因子,由於 \(a\) 為排列所以時間複雜度為 \(\text{O}(n \ln n\log n)\)

#include<bits/stdc++.h>
using namespace std;
int n,d,u,v,t,a[200001],p[200001],mu[200001],g[200001],son[200001],siz[200001],ans[200001];
long long w,now,val[200001],sum[200001];
basic_string <int> G[200001];
vector <pair<int,int>> F[200001];
void dfs3(int x,int u,int h,int v){
	if(v){
		for(auto [i,j]:F[a[x]]) sum[i]+=g[a[x]];
		for(auto [i,j]:F[a[x]]) if(j) now+=g[a[x]]*mu[i]*sum[j];
	}
	else{
		for(auto [i,j]:F[a[x]]) if(j) now-=g[a[x]]*mu[i]*sum[j];
		for(auto [i,j]:F[a[x]]) sum[i]-=g[a[x]];
	}
	for(int y:G[x]) if(y!=u&&y!=h) dfs3(y,x,h,v);
}
void dfs2(int x,int u,int k){
	for(int y:G[x]) if(y!=u&&y!=son[x]) dfs2(y,x,0);
	if(son[x]) dfs2(son[x],x,1);
	dfs3(x,u,son[x],1),ans[x]=now;
	if(!k) dfs3(x,u,0,0);
}
void dfs1(int x,int u){
	siz[x]=1,val[x]=1;
	for(int i=1;i<=d+1&&val[x]<=1ll*n*n;i++) val[x]*=x;
	for(int y:G[x]) if(y!=u) dfs1(y,x),siz[x]+=siz[y],siz[y]>siz[son[x]]&&(son[x]=y,0);
}
int main(){
	scanf("%d%d",&n,&d),mu[1]=g[1]=1;
	for(int i=1;i<n;i++) scanf("%d%d",&u,&v),G[u]+=v,G[v]+=u;
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	dfs1(1,0);
	for(int i=2;i<=n;i++){
		if(!p[i]) p[++t]=i,mu[i]=g[i]=-1;
		for(int j=1;j<=t&&i*p[j]<=n;j++){
			mu[i*p[j]]=-mu[i],g[i*p[j]]=-g[i],p[i*p[j]]=1;
			if(i%p[j]==0){mu[i*p[j]]=0;break;}
		}
		for(int j=2;j<=n&&val[j]<=i;j++) if(i%val[j]==0){g[i]=0;break;}
	}
	for(int i=1;i<=n;i++) for(int j=i;j<=n;j+=i) w=val[i]/__gcd(val[i],1ll*j),F[j].push_back({i,w<=n?w:0});
	dfs2(1,0,1);
	for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
	return 0;
}

相關文章