cf809e Surprise Me!

本文深入探讨了欧拉函数的性质及其与莫比乌斯反演的关系,通过点权为1到n的全排列,介绍了如何利用欧拉函数和莫比乌斯反演解决特定的数学问题,包括复杂度分析和算法实现。

传送门

对于欧拉函数,有:
φ ( a ∗ b ) = φ ( a ) ∗ φ ( b ) ∗ g c d ( a , b ) φ ( g c d ( a , b ) ) \varphi (a*b)=\varphi(a)*\varphi(b)*\frac{gcd(a,b)}{\varphi(gcd(a,b))} φ(ab)=φ(a)φ(b)φ(gcd(a,b))gcd(a,b)
证明:把 a a a b b b质因数分解即可。

那么首先由于点权为 1 1 1~ n n n的全排列,所以枚举点权,记录一下点权的所在点。
a n s = ∑ φ ( i ) ∗ φ ( j ) ∗ g c d ( i , j ) φ ( g c d ( i , j ) ) ∗ d i s ( p [ i ] , p [ j ] ) ans=\sum\varphi(i)*\varphi(j)*\frac{gcd(i,j)}{\varphi(gcd(i,j))}*dis(p[i],p[j]) ans=φ(i)φ(j)φ(gcd(i,j))gcd(i,j)dis(p[i],p[j])
p [ i ] p[i] p[i]:点权为 i i i的点对应原树上的点为 p [ i ] p[i] p[i]
这里 ∑ \sum 没有标明上下界表示枚举树上的所有点对。

然后枚举 g c d gcd gcd(套路):
a n s = ∑ d = 1 n d φ ( d ) ∑ [ g c d ( i , j ) = = d ] φ ( i ) ∗ φ ( j ) ∗ d i s ( p [ i ] , p [ j ] ) ans=\sum_{d=1}^{n} {\frac{d}{\varphi(d)}} \sum {[gcd(i,j)==d]\varphi(i)*\varphi(j)*dis(p[i],p[j])} ans=d=1nφ(d)d[gcd(i,j)==d]φ(i)φ(j)dis(p[i],p[j])

后面是一个可以莫比乌斯反演的形式。我们令:
g ( d ) = ∑ [ g c d ( i , j ) = = d ] φ ( i ) ∗ φ ( j ) ∗ d i s ( p [ i ] , p [ j ] ) g(d)= \sum {[gcd(i,j)==d]\varphi(i)*\varphi(j)*dis(p[i],p[j])} g(d)=[gcd(i,j)==d]φ(i)φ(j)dis(p[i],p[j])
f ( d ) = ∑ [ d ∣ g c d ( i , j ) ] φ ( i ) ∗ φ ( j ) ∗ d i s ( p [ i ] , p [ j ] ) f(d)= \sum {[d|gcd(i,j)]\varphi(i)*\varphi(j)*dis(p[i],p[j])} f(d)=[dgcd(i,j)]φ(i)φ(j)dis(p[i],p[j])

于是有:
f ( d ) = ∑ d ∣ k g ( k ) f(d)=\sum_{d|k}g(k) f(d)=dkg(k)
由莫比乌斯反演:
f ( d ) = ∑ d ∣ k g ( k ) ⟺ g ( d ) = ∑ d ∣ k μ ( k d ) f ( k ) f(d)=\sum_{d|k}g(k) \Longleftrightarrow g(d)=\sum_{d|k} {\mu(\frac{k}{d})f(k)} f(d)=dkg(k)g(d)=dkμ(dk)f(k)

回过头来看:
a n s = ∑ d = 1 n d φ ( d ) g ( d ) ans=\sum_{d=1}^{n} {\frac{d}{\varphi(d)}} g(d) ans=d=1nφ(d)dg(d)
a n s = ∑ d = 1 n d φ ( d ) ∑ d ∣ k μ ( k d ) f ( k ) ans=\sum_{d=1}^{n} {\frac{d}{\varphi(d)}} \sum_{d|k} {\mu(\frac{k}{d})f(k)} ans=d=1nφ(d)ddkμ(dk)f(k)
如果我们可以预处理出所有的 f f f,我们就可以在 O ( n + n l o g n ) O(n+nlogn) O(n+nlogn)的时间内枚举 d d d以及 d d d的倍数然后得到答案了。

于是考虑怎么预处理 f f f

f ( d ) = ∑ [ d ∣ g c d ( i , j ) ] φ ( i ) ∗ φ ( j ) ∗ d i s ( p [ i ] , p [ j ] ) f(d)= \sum {[d|gcd(i,j)]\varphi(i)*\varphi(j)*dis(p[i],p[j])} f(d)=[dgcd(i,j)]φ(i)φ(j)dis(p[i],p[j])

f ( d ) = ∑ d ∣ i ∑ d ∣ j φ ( i ) ∗ φ ( j ) ∗ d i s ( p [ i ] , p [ j ] ) f(d)= \sum_{d|i} \sum_{d|j}{\varphi(i)*\varphi(j)*dis(p[i],p[j])} f(d)=didjφ(i)φ(j)dis(p[i],p[j])

f ( d ) = ∑ d ∣ i ∑ d ∣ j φ ( i ) ∗ φ ( j ) ∗ ( d e p [ p [ i ] ] + d e p [ p [ j ] ] − 2 ∗ d e p [ l c a ] ) f(d)= \sum_{d|i} \sum_{d|j}{\varphi(i)*\varphi(j)*(dep[p[i]]+dep[p[j]]-2*dep[lca])} f(d)=didjφ(i)φ(j)(dep[p[i]]+dep[p[j]]2dep[lca])

f ( d ) = ∑ d ∣ i ∑ d ∣ j φ ( i ) ∗ φ ( j ) ∗ d e p [ p [ i ] ] + ∑ d ∣ i ∑ d ∣ j φ ( i ) ∗ φ ( j ) ∗ d e p [ p [ j ] ] − ∑ d ∣ i ∑ d ∣ j φ ( i ) ∗ φ ( j ) ∗ d e p [ l c a ] ∗ 2 f(d)= \sum_{d|i} \sum_{d|j}{\varphi(i)*\varphi(j)*dep[p[i]]}+ \sum_{d|i} \sum_{d|j}{\varphi(i)*\varphi(j)*dep[p[j]]}- \sum_{d|i} \sum_{d|j}{\varphi(i)*\varphi(j)*dep[lca]*2} f(d)=didjφ(i)φ(j)dep[p[i]]+didjφ(i)φ(j)dep[p[j]]didjφ(i)φ(j)dep[lca]2

我们枚举 d d d,提取出点权为 d d d的倍数的点。发现前面两坨是一样的,可以直接算,而后面一坨可以建一棵虚树出来 d p dp dp
每次虚树的点是 n d \frac{n}{d} dn个,求一次是 O ( n d ) O(\frac{n}{d}) O(dn)的。于是可以在 O ( n l o g n ) O(nlogn) O(nlogn)的时间里面把 f f f求出来。
然后把 f f f套进刚才 a n s ans ans的那个式子里就行了。
最后要记得乘上 1 n ∗ ( n − 1 ) \frac{1}{n*(n-1)} n(n1)1

①建虚树的时候是强制 1 1 1号点为根节点
②虚树上不是所有点都是关键点,因为有一些辅助的 l c a lca lca节点,所以要给关键点打上标记。

#include<bits/stdc++.h>
#define re register
#define cs const

cs int N=2e5+10,Log=18;
int mark[N],P[N],mu[N],phi[N],cnt=0;

namespace IO{
	cs int Rlen=1<<22|1;
	char buf[Rlen],*p1,*p2;
	inline char gc(){return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;}
	template<typename T>
	inline T get(){
		char ch;T x;
		while(!isdigit(ch=gc()));x=ch^48;
		while(isdigit(ch=gc())) x=((x+(x<<2))<<1)+(ch^48);
		return x;
	}
	inline int gi(){return get<int>();}
}
using namespace IO;

int dep[N],dfn[N],t[N<<1],tot=0;
int dp[N<<1][Log+1];

namespace GRAPH{
	int Head[N],Next[N<<1],V[N<<1],cnt=0;
	inline void add(int u,int v){Next[++cnt]=Head[u],V[cnt]=v,Head[u]=cnt;}
	inline void dfs(int u,int fa){
		t[dfn[u]=++tot]=u,dep[u]=dep[fa]+1;
		for(int re i=Head[u],v=V[i];i;v=V[i=Next[i]])
			if(v!=fa) dfs(v,u),t[++tot]=u;
	}
	inline void RMQ(){
		for(int re j=0;(1<<j)<tot;++j)
			for(int re i=0;i+(1<<j)<=tot;++i)
				if(j==0) dp[i][j]=i;
				else{
					if(dep[t[dp[i][j-1]]]<dep[t[dp[i+(1<<(j-1))][j-1]]])
						dp[i][j]=dp[i][j-1];
					else dp[i][j]=dp[i+(1<<(j-1))][j-1];
				}
	}
	inline int query(int p1,int p2){
		int k=log2(p2-p1+1);
		if(dep[t[dp[p1][k]]]<dep[t[dp[p2-(1<<k)+1][k]]])
			return t[dp[p1][k]];
		else return t[dp[p2-(1<<k)+1][k]];
	}
	inline int lca(int u,int v){
		if(dfn[u]>dfn[v]) std::swap(u,v);
		return query(dfn[u],dfn[v]);
	}
}
using GRAPH::lca;

namespace CALC{
	cs int mod=1e9+7;

	inline int plu(int x,int y){return x+y>=mod?x+y-mod:x+y;}
	inline int dec(int x,int y){return x-y<0?x-y+mod:x-y;}
	inline int mul(int x,int y){return 1ll*x*y%mod;}
	inline int sqr(int x){return 1ll*x*x%mod;}
	inline int quickpow(int a,int b,int ret=1){for(;b;b>>=1,a=sqr(a))if(b&1)ret=mul(ret,a);return ret;}
	inline int inv(int x){return quickpow(x,mod-2);}

	inline void linear_sieves(){
		mark[1]=phi[1]=mu[1]=1;
		for(int re i=2;i<N;++i){
			if(!mark[i]) P[++cnt]=i,mu[i]=mod-1,phi[i]=i-1;
			for(int re j=1;j<=cnt&&i*P[j]<N;++j){
				mark[i*P[j]]=1;
				if(i%P[j]) phi[i*P[j]]=phi[i]*(P[j]-1),mu[i*P[j]]=dec(mod,mu[i]);
				else{phi[i*P[j]]=phi[i]*P[j],mu[i*P[j]]=0;break;}
			}
		}
	}
}
using CALC::mul;
using CALC::sqr;
using CALC::inv;
using CALC::dec;
using CALC::plu;

int n,pos[N],val[N],F[N],ans=0;

namespace V_TREE{
	cs int Log=18;
	int Head[N],Next[N<<1],V[N<<1],cnt=0;
	int sum[N],tag[N],st[N],q[N],top=0,qn=0;
	inline bool cmp(int a,int b){return dfn[a]<dfn[b];}
	inline void init(){cnt=top=qn=0;}
	inline void add(int u,int v){Next[++cnt]=Head[u],V[cnt]=v,Head[u]=cnt;}
	inline void insert(int u){
		if(top==1) return void(st[++top]=u);
		int g=lca(u,st[top]);
		if(g==st[top]) return void(st[++top]=u);
		while(top>1&&dfn[g]<=dfn[st[top-1]])
			add(st[top-1],st[top]),--top;
		if(g!=st[top]) add(g,st[top]),st[top]=g;
		st[++top]=u;
	}
	inline int dfs(int u,int ret=0,int now=0){
		sum[u]=tag[u]?phi[val[u]]:0;
		for(int re i=Head[u],v=V[i];i;v=V[i=Next[i]]){
			ret=plu(ret,dfs(v)),now=dec(now,sqr(sum[v]));
			sum[u]=plu(sum[u],sum[v]);
		}now=plu(now,sqr(sum[u])),tag[u]=Head[u]=0;
		return plu(ret,mul(dep[u]<<1,now));
	}
	inline int get_f(int k,int sum_phi=0,int sum_mul=0){
		init();
		for(int re i=k;i<=n;i+=k)
			tag[q[++qn]=pos[i]]=1,sum_phi=plu(sum_phi,phi[i]),
			sum_mul=plu(sum_mul,mul(phi[i],dep[pos[i]]));
		std::sort(q+1,q+qn+1,cmp),st[top=1]=1;
		for(int re i=1;i<=qn;++i) if(q[i]!=1) insert(q[i]);
		while(--top) add(st[top],st[top+1]);
		return dec(mul(2,mul(sum_mul,sum_phi)),dfs(1));
	}
}
int main(){
#ifdef wcr
	freopen("surprise.in","r",stdin);
#endif
	CALC::linear_sieves();
	n=gi();
	for(int re i=1;i<=n;++i) pos[val[i]=gi()]=i;
	for(int i=1;i<n;++i){
		int x=gi(),y=gi();
		GRAPH::add(x,y),GRAPH::add(y,x);
	}GRAPH::dfs(1,0),GRAPH::RMQ();
	for(int re i=1;i<=n;++i) F[i]=V_TREE::get_f(i);
	for(int re d=1,sum=0;d<=n;++d,sum=0){
		for(int re k=d,i=1;k<=n;k+=d,++i)
			sum=plu(sum,mul(mu[i],F[k]));
		ans=plu(ans,mul(sum,mul(d,inv(phi[d]))));
	}printf("%d\n",mul(inv(mul(n,n-1)),ans));
}
内容概要:本文为《科技类企业品牌传播白皮书》,系统阐述了新闻媒体发稿、自媒体博主种草与短视频矩阵覆盖三大核心传播策略,并结合“传声港”平台的AI工具与资源整合能力,提出适配科技企业的品牌传播解决方案。文章深入分析科技企业传播的特殊性,包括受众圈层化、技术复杂性与传播通俗性的矛盾、产品生命周期影响及2024-2025年传播新趋势,强调从“技术输出”向“价值引领”的战略升级。针对三种传播方式,分别从适用场景、操作流程、效果评估、成本效益、风险防控等方面提供详尽指南,并通过平台AI能力实现资源智能匹配、内容精准投放与全链路效果追踪,最终构建“信任—种草—曝光”三位一体的传播闭环。; 适合人群:科技类企业品牌与市场负责人、公关传播从业者、数字营销管理者及初创科技公司创始人;具备一定品牌传播基础,关注效果可量化与AI工具赋能的专业人士。; 使用场景及目标:①制定科技产品全生命周期的品牌传播策略;②优化媒体发稿、KOL合作与短视频运营的资源配置与ROI;③借助AI平台实现传播内容的精准触达、效果监测与风险控制;④提升品牌在技术可信度、用户信任与市场影响力方面的综合竞争力。; 阅读建议:建议结合传声港平台的实际工具模块(如AI选媒、达人匹配、数据驾驶舱)进行对照阅读,重点关注各阶段的标准化流程与数据指标基准,将理论策略与平台实操深度融合,推动品牌传播从经验驱动转向数据与工具双驱动。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值