给定一个排列 \(a_i\) 和一棵树,求:

\[\frac 1 {n(n-1)}\sum_{i=1}^n\sum_{j=1}^n \varphi(a_i \times a_j) \times dis(i,j)
\]

因为 \(a\) 是一个排列,我们考虑对其求逆。

设 \(p_{a_i}=i\),则有:

\[\sum_{i=1}^n\sum_{j=1}^n\varphi(ij) \times dis(p_i,p_j)
\]

众所周知有 \(\varphi(nm)=\frac {\varphi(n)\varphi(m)\gcd(n,m)} {\varphi(\gcd(n,m))}\)

\[\sum_{i=1}^n\sum_{j=1}^n\frac {\varphi(i)\varphi(j)\gcd(i,j)} {\varphi(\gcd(i,j))} \times dis(p_i,p_j)
\]

接下来就全是套路了。

\[\sum_{d=1}^n\frac d {\varphi(d)}\sum_{i=1}^n\sum_{j=1}^n\varphi(i)\varphi(j)dis(p_i,p_j)[\gcd(i,j)=d]
\]
\[\sum_{d=1}^n \frac d {\varphi(d)} \sum_{i=1}^{\lfloor \frac n d \rfloor}\sum_{j=1}^{\lfloor \frac n d \rfloor}\varphi(id)\varphi(jd)dis(p_i,p_j)\sum_{x|i,x|j}\mu(x)
\]
\[\sum_{d=1}^n\frac d {\varphi(d)}\sum_{x=1}^{\lfloor \frac n d \rfloor}\mu(x)\sum_{i=1}^{\lfloor \frac n {dx} \rfloor}\sum_{j=1}^{\lfloor \frac n {dx} \rfloor}\varphi(idx)\varphi(jdx)dis(p_i,p_j)
\]
\[\sum_{T=1}^n(\frac {id} {\varphi} * \mu)(T)\sum_{i=1}^{\lfloor \frac n T \rfloor}\sum_{j=1}^{\lfloor \frac n T \rfloor}\varphi(iT)\varphi(jT) \times dis(p_i,p_j)
\]

于是枚举 \(T\),枚举 \(T\) 的倍数,对其节点建立虚树,然后统计答案。

\[\varphi(i)\varphi(j)(d_{p_i}+d_{p_j}-2 \times d_{lca(p_i,p_j)})
\]

前面的部分可以 \(O(n)\) 计算,后面的在 \(LCA\) 处统计贡献就行了。

复杂度应该是 \(O(n\log^2n)\) 的。

对 \(O(n\log n)\) 的瞎 yy

在 DFS 的时候,对虚树的序列直接插入点即可。

枚举因数随便预处理一下就 \(O(n\log n)\) 了。

以下是卡常 114514 次后的代码。因为常数问题最后还是选择了树剖LCA

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("no-stack-protector")
#include<algorithm>
#include<iostream>
#include<cctype>
typedef unsigned ui;
const ui M=2e5+5,mod=1e9+7;
ui n,m,cnt,a[M],p[M],h[M],V[M],F[M],phi[M],pos[M];ui Top,pri[M];ui d[M],f[M],siz[M],son[M],top[M];
ui sum,ans;ui tp,stk[M];char buf[1<<21|1],*Jerry=buf;ui L[M],l[M],f1[M*19],f2[M*19],*G[M],*fac[M],*now1=f1,*now2=f2;
inline char Getchar(){
return*Jerry=='\0'&&std::cin.read(Jerry=buf,1<<21),*Jerry++;
}
inline ui read(){
ui n(0);char s;while(!isdigit(s=Getchar()));while(n=n*10+(s&15),isdigit(s=Getchar()));return n;
}
struct Edge{
ui v,nx;
}e[M<<1];
inline void Add(const ui&u,const ui&v){
e[++cnt]=(Edge){v,h[u]};h[u]=cnt;
}
inline ui pow(ui a,ui b){
ui ans(1);
for(;b;b>>=1,a=1ull*a*a%mod)if(b&1)ans=1ull*ans*a%mod;
return ans;
}
void DFS1(const ui&u){
d[u]=d[f[u]]+1;siz[u]=1;
for(ui v,E=h[u];E;E=e[E].nx)if((v=e[E].v)^f[u]){
f[v]=u;DFS1(v);siz[u]+=siz[v];if(siz[v]>siz[son[u]])son[u]=v;
}
}
void DFS2(const ui&u,const ui&tp){
ui*g=fac[a[u]];top[u]=tp;for(ui x=0;x^L[a[u]];++x)if(F[g[x]])G[g[x]][l[g[x]]++]=a[u];
if(!son[u])return;DFS2(son[u],tp);for(ui E=h[u];E;E=e[E].nx)if(e[E].v^f[u]&&e[E].v^son[u])DFS2(e[E].v,e[E].v);
}
inline ui LCA(ui u,ui v){
while(top[u]^top[v]){
if(d[top[u]]>d[top[v]])u=f[top[u]];
else v=f[top[v]];
}
return d[u]>d[v]?v:u;
}
void Solve(const ui&u){
for(ui v,E=h[u];E;E=e[E].nx){
Solve(v=e[E].v);sum=(sum+2ull*V[u]*V[v]%mod*(mod-d[u]))%mod;V[u]=(V[u]+V[v])%mod;h[v]=V[v]=0;
}
if(u==1)h[u]=V[u]=0;
}
inline void Insert(const ui&u){
const ui&v=LCA(u,stk[tp]);while(tp^1&&d[stk[tp-1]]>d[v])Add(stk[tp-1],stk[tp]),--tp;
if(stk[tp]^v)Add(v,stk[tp--]);if(stk[tp]^v||!tp)stk[++tp]=v;if(stk[tp]^u)stk[++tp]=u;
}
inline void calc(const ui&x){
ui S(0),*g=G[x];stk[tp=1]=1;cnt=sum=0;
for(ui u=0;u^l[x];++u)S=(S+phi[g[u]])%mod,Insert(p[g[u]]),V[p[g[u]]]=phi[g[u]];
while(tp^1)Add(stk[tp-1],stk[tp]),--tp;
for(ui u=0;u^l[x];++u)sum=(sum+1ull*(S+mod-phi[g[u]])*d[p[g[u]]]%mod*phi[g[u]])%mod;
Solve(1);ans=(ans+2ull*sum*F[x])%mod;
}
inline void sieve(){
ui i,j,x;F[1]=phi[1]=1;
for(i=2;i<=n;++i){
if(!pos[i])pri[pos[i]=++Top]=i,F[i]=pow(phi[i]=i-1,mod-2);
for(j=1;j<=pos[i]&&(x=i*pri[j])<=n;++j){
pos[x]=j;phi[x]=j==pos[i]?phi[i]*pri[j]:phi[i]*phi[pri[j]];
F[x]=j==pos[i]?0:1ull*F[i]*F[pri[j]]%mod;
}
}
for(i=1;i<=n;++i)for(j=1;(x=i*j)<=n;++j)++L[x];
for(i=1;i<=n;++i)G[i]=now1,now1+=n/i,fac[i]=now2,now2+=L[i];
for(i=1;i<=n;++i)for(j=1;(x=i*j)<=n;++j)fac[x][--L[x]]=i;
for(i=1;i<n;++i)L[i]=fac[i+1]-fac[i];L[n]=now2-fac[n];
}
signed main(){
ui i,u,v;n=read();sieve();for(i=1;i<=n;++i)p[a[i]=read()]=i;
for(i=1;i<n;++i)u=read(),v=read(),Add(u,v),Add(v,u);DFS1(1);DFS2(1,1);
for(i=1;i<=n;++i)h[i]=0;for(i=1;i<=n;++i)if(F[i])calc(i);
printf("%u",1ull*ans*pow(n*(n-1ull)%mod,mod-2)%mod);
}

CF809E题解的更多相关文章

  1. 【CF809E】Surprise me!(动态规划,虚树,莫比乌斯反演)

    [CF809E]Surprise me!(动态规划,虚树,莫比乌斯反演) 题面 洛谷 CodeForces 翻译: 给定一棵\(n\)个节点的树,每个点有一个权值\(a[i]\),保证\(a[i]\) ...

  2. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  3. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  4. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  5. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  6. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  7. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  8. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  9. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

随机推荐

  1. js null和{}区别

    {}是一个不完全空的对象,因为他的原型链上还有Object呢,而null就是完全空的对象,啥也没有,原型链也没有,所以null instanceof Object === false;[]就更不用说了 ...

  2. java多线程编程(二)

    1. wait 和 sleep 区别? 1.wait可以指定时间也可以不指定,sleep必须指定时间. 2.在同步中时,对cpu的执行权和锁的处理不同.  wait:释放执行权,释放锁.  sleep ...

  3. squid 代理服务器应用

    squid 代理服务器应用 1.Squid 代理服务器 : Squid 主要提供缓存加速.应用层过滤控制的功能.  代理的工作机制: 代替客户机向网站请求数据,从而可以隐藏用户的真实IP地址. 将获得 ...

  4. 社交网络分析的 R 基础:(六)绘图操作

    R 语言强大的可视化功能在科学研究中非常受欢迎,丰富的类库使得 R 语言可以绘制各种各样的图表.当然这些与本章内容毫无关系,因为笔者对绘制图表了解有限,仅限于能用的程度.接下来的内容无需额外安装任何包 ...

  5. 「BUAA OO Pre」Git生成多个ssh key并连接GitLab仓库

    「BUAA OO Pre」Git生成多个ssh key并连接GitLab仓库 Part 0 前言 写作背景 笔者在配置学校GitLab的ssh key时遇到一些问题,原因应为曾经配置过GitHub的s ...

  6. Dubbo基础三之配置方式简述

    Dubbo基础一之实战初体验 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中,体验了两种配置方式一种注解一种xml.其中xml是在注解配置失败没有找到解决方法后选择xml替代体验的.那 ...

  7. jenkins发布代码选择不同分支

    jenkins上传代码分支以前都是用变量的方式,手动实现.过程就像这样 构建时候的界面就像下面这样,需要手动输入分支版本. 或者有固定的上线分支,用参数化构建 选项参数 来选择.总之这些方法比较传统, ...

  8. SpringBoot+JavaMailSender+Redis完整找回密码功能

    导入maven坐标 <parent> <groupId>org.springframework.boot</groupId> <artifactId>s ...

  9. 开源爱好者月刊《HelloGitHub》第 71 期

    兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. https://github.com/521xueweiha ...

  10. DNS中的FQDN

    FQDN:(Fully Qualified Domain Name)全限定域名:同时带有主机名和域名的名称.(通过符号".") 例如:主机名是bigserver,域名是mycomp ...