【学习笔记】CF809E Surprise me!

练习套路的一道题。

首先 ϕ ( i j ) \phi(ij) ϕ(ij)怎么拆?这里要用到一个不怎么常见的套路, ϕ ( i j ) = ϕ ( i ) ϕ ( j ) gcd ⁡ ( i , j ) ϕ ( gcd ⁡ ( i , j ) ) \phi(ij)=\frac{\phi(i)\phi(j)\gcd(i,j)}{\phi(\gcd(i,j))} ϕ(ij)=ϕ(gcd(i,j))ϕ(i)ϕ(j)gcd(i,j)

让我们观察这个式子: ∑ d = 1 n d ϕ ( d ) ∑ i = 1 n ∑ j = 1 n ϕ ( i ) ϕ ( j ) [ gcd ⁡ ( i , j ) = d ] dist(i,j) \sum_{d=1}^n\frac{d}{\phi(d)}\sum_{i=1}^n\sum_{j=1}^n\phi(i)\phi(j)[\gcd(i,j)=d]\text{dist(i,j)} d=1nϕ(d)di=1nj=1nϕ(i)ϕ(j)[gcd(i,j)=d]dist(i,j)

首先 ϕ ( i ) ϕ ( j ) \phi(i)\phi(j) ϕ(i)ϕ(j)可以看成两个点权之积,其次后面的艾佛森括号表示的是“恰好”的意思,那么我们可以想到将条件改写成 i , j i,j i,j均为 d d d的倍数。

考察: ∑ d ∣ i ∑ d ∣ j ϕ ( i ) ϕ ( j ) dist(i,j) \sum_{d|i}\sum_{d|j}\phi(i)\phi(j)\text{dist(i,j)} didjϕ(i)ϕ(j)dist(i,j) 这个式子不就可以在虚树上统计答案吗?

那么我们只需容斥即可。记 g ( d ) = ∑ d ∣ i ∑ d ∣ j ϕ ( i ) ϕ ( j ) dist(i,j) g(d)=\sum_{d|i}\sum_{d|j}\phi(i)\phi(j)\text{dist(i,j)} g(d)=didjϕ(i)ϕ(j)dist(i,j) f ( d ) = ∑ i = 1 n ∑ j = 1 n ϕ ( i ) ϕ ( j ) [ gcd ⁡ ( i , j ) = d ] dist(i,j) f(d)=\sum_{i=1}^n\sum_{j=1}^n\phi(i)\phi(j)[\gcd(i,j)=d]\text{dist(i,j)} f(d)=i=1nj=1nϕ(i)ϕ(j)[gcd(i,j)=d]dist(i,j)。那么 g ( d ) = ∑ d ∣ d ′ f ( d ′ ) g(d)=\sum_{d|d'}f(d') g(d)=ddf(d),显然可以得到 f ( d ) = ∑ d ∣ d ′ g ( d ′ ) μ ( d ′ d ) f(d)=\sum_{d|d'}g(d')\mu(\frac{d'}{d}) f(d)=ddg(d)μ(dd),因此只需计算 g ( d ) g(d) g(d)

只需把 d d d的倍数的点建虚树即可,这里不再赘述。

复杂度 O ( n log ⁡ 2 n ) O(n\log^2 n) O(nlog2n)

出题人是bot吧

#include<bits/stdc++.h> #define pb push_back #define ll long long using namespace std; const int mod=1e9+7; const int N=200005; int n,a[N],rk[N],dfn[N],son[N],fa[N],num,dep[N],siz[N],tp[N],dis[N]; ll f[N]; vector<int>g[N],g2[N]; ll fpow(ll x,ll y=mod-2){ ll z(1); for(;y;y>>=1){ if(y&1)z=z*x%mod; x=x*x%mod; }return z; } int Lca(int x,int y){ int fx=tp[x],fy=tp[y]; while(fx!=fy){ if(dep[fx]>dep[fy])x=fa[fx]; else y=fa[fy]; fx=tp[x],fy=tp[y]; }return dep[x]<dep[y]?x:y; } void dfs(int u,int topf){ dfn[u]=++num,fa[u]=topf,siz[u]=1,dep[u]=dep[topf]+1; for(auto v:g[u]){ if(v!=topf){ dfs(v,u),siz[u]+=siz[v]; if(siz[v]>siz[son[u]])son[u]=v; } } } void dfs2(int u,int topf){ tp[u]=topf; if(son[u])dfs2(son[u],topf); for(auto v:g[u]){ if(!tp[v]){ dfs2(v,v); } } } int prime[N],Cnt,mu[N],Vis[N],phi[N]; void init(int n){ mu[1]=phi[1]=1; for(int i=2;i<=n;i++){ if(!Vis[i])prime[++Cnt]=i,mu[i]=-1,phi[i]=i-1; for(int j=1;j<=Cnt&&prime[j]<=n/i;j++){ Vis[i*prime[j]]=1; if(i%prime[j])mu[i*prime[j]]=-mu[i],phi[i*prime[j]]=phi[i]*(prime[j]-1); else { phi[i*prime[j]]=phi[i]*prime[j]; break; } } } } int p[N],vis[N],m,cnt,s[N]; vector<int>vec; bool cmp(int x,int y){ return dfn[x]<dfn[y]; } ll S,sum[N],res; void dfs3(int u,int id){ sum[u]=0;if(vis[u])sum[u]=(sum[u]+phi[a[u]])%mod; for(auto v:g2[u]){ dfs3(v,id); f[id]=(f[id]+2*sum[v]*(S-sum[v])%mod*dis[v]%mod)%mod,sum[u]=(sum[u]+sum[v])%mod; } } void add(int x,int y){ if(dfn[x]>dfn[y])swap(x,y); g2[x].pb(y),dis[y]=dep[y]-dep[x]; } int gcd(int x,int y){ return y==0?x:gcd(y,x%y); } int main(){ ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); cin>>n,init(n);for(int i=1;i<=n;i++)cin>>a[i],rk[a[i]]=i; for(int i=1;i<n;i++){ int x,y;cin>>x>>y,g[x].pb(y),g[y].pb(x); }dfs(1,0),dfs2(1,1); for(int i=1;i<=n;i++){ m=S=0; for(int j=i;j<=n;j+=i)p[++m]=rk[j],S=(S+phi[j])%mod,vis[rk[j]]=1,vec.pb(rk[j]); s[cnt=1]=1,vec.pb(1); sort(p+1,p+1+m,cmp); for(int i=1;i<=m;i++){ if(p[i]==1)continue; int u=p[i],v=Lca(u,s[cnt]); if(s[cnt]==v)s[++cnt]=u; else{ int lst=0; while(dep[s[cnt]]>dep[v]){ if(lst)add(s[cnt],lst); lst=s[cnt--]; } if(s[cnt]==v){ add(s[cnt],lst),s[++cnt]=u; } else{ add(v,lst),s[++cnt]=v,vec.pb(v),s[++cnt]=u; } } }for(int i=1;i<cnt;i++)add(s[i],s[i+1]); dfs3(1,i); for(int j=0;j<vec.size();j++)vis[vec[j]]=0,g2[vec[j]].clear();vec.clear(); } for(int i=1;i<=n;i++){ ll tot=0; for(int j=i;j<=n;j+=i){ tot=(tot+mu[j/i]*f[j]%mod)%mod; } res=(res+tot*i%mod*fpow(phi[i])%mod)%mod; } cout<<(res+mod)%mod*fpow(n)%mod*fpow(n-1)%mod; }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530065.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(9)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示