给定一个排列 \(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. Ajax向服务器发起请求

    Ajax向服务器发起请求的三个步骤: 1:创建Ajax 2:打开Ajax,打开Ajax请求 3:向服务器发起请求:需要知道地址和是get请求还是post方法 向服务器发起请求的两个方法:open 和 ...

  2. js 对象的深克隆

    前端笔试或者面试的时候,很喜欢问的一个问题就是对象的深度克隆,或者说是对象的深度复制.其实这个问题说容易很容易,但是要说全面也挺不易. 要弄明白对象的克隆,首先要明白js中对象的组成.在js中一切实例 ...

  3. 关于CSS3样式中的前缀问题

    作为新手,有的时候在写css时分不清什么属性需要用到前缀,或者用什么前缀,下面是我平时学习的一些总结. 在了解这些前缀之前,先介绍一下各大主流浏览器的内核: IE--trident(国内很多双核浏览器 ...

  4. 3M 高可用架构----拓展

    3M 高可用架构 一.MMM 1. MMM的概述 MMM(Master-Master replication manager for MySQL,MySQL主主复制管理器)是一套支持双主故障切换和双主 ...

  5. 【NetCore】依赖注入的一些理解与分享

    依赖注入 DI 前言 声明:我是一个菜鸟,此文是自己的理解,可能正确,可能有误.仅供学习参考帮助理解,如果直接拷贝代码使用造成损失概不负责. 相关的文章很多,我就仅在代码层面描述我所理解的依赖注入是个 ...

  6. matlab构建栅格地图绘图思路

    matlab构建栅格地图绘图思路 近来因研究需要,调研并思考了栅格地图的生成方法,暂时总结以备不时之需. 栅格的建立最需要注意栅格粒度的问题,即根据需要调整栅格的边长,目前有两种思路一种是固定栅格边长 ...

  7. LeetCode随缘刷题之最长回文子串

    这一题我用的相对比较笨的方法. 相对于大佬们用的动态规划法,比较复杂.但却更容易理解,我主要是通过记录下标来确定最长回文串的. package leetcode.day_12_06; /** * 给你 ...

  8. 赠送4本《 PHP 程序员面试笔试宝典》

    < PHP 程序员面试笔试宝典>历时一年,由机械工业出版社出版,在 2018 年 11 月问世.全书共八个章节,涉及 面试笔试经验技巧.PHP 基础知识.PHP 进阶知识,PHP 面向对象 ...

  9. Deformable Templates For Eye Detection

    1 Abstract This approach was published On "Deformable Templates for Face Recognition" by A ...

  10. Solution -「CF 487E」Tourists

    \(\mathcal{Description}\)   Link.   维护一个 \(n\) 个点 \(m\) 条边的简单无向连通图,点有点权.\(q\) 次操作: 修改单点点权. 询问两点所有可能路 ...