CF809E题解
给定一个排列 \(a_i\) 和一棵树,求:
\]
因为 \(a\) 是一个排列,我们考虑对其求逆。
设 \(p_{a_i}=i\),则有:
\]
众所周知有 \(\varphi(nm)=\frac {\varphi(n)\varphi(m)\gcd(n,m)} {\varphi(\gcd(n,m))}\)
\]
接下来就全是套路了。
\]
\]
\]
\]
于是枚举 \(T\),枚举 \(T\) 的倍数,对其节点建立虚树,然后统计答案。
\]
前面的部分可以 \(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题解的更多相关文章
- 【CF809E】Surprise me!(动态规划,虚树,莫比乌斯反演)
[CF809E]Surprise me!(动态规划,虚树,莫比乌斯反演) 题面 洛谷 CodeForces 翻译: 给定一棵\(n\)个节点的树,每个点有一个权值\(a[i]\),保证\(a[i]\) ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
随机推荐
- Ajax向服务器发起请求
Ajax向服务器发起请求的三个步骤: 1:创建Ajax 2:打开Ajax,打开Ajax请求 3:向服务器发起请求:需要知道地址和是get请求还是post方法 向服务器发起请求的两个方法:open 和 ...
- js 对象的深克隆
前端笔试或者面试的时候,很喜欢问的一个问题就是对象的深度克隆,或者说是对象的深度复制.其实这个问题说容易很容易,但是要说全面也挺不易. 要弄明白对象的克隆,首先要明白js中对象的组成.在js中一切实例 ...
- 关于CSS3样式中的前缀问题
作为新手,有的时候在写css时分不清什么属性需要用到前缀,或者用什么前缀,下面是我平时学习的一些总结. 在了解这些前缀之前,先介绍一下各大主流浏览器的内核: IE--trident(国内很多双核浏览器 ...
- 3M 高可用架构----拓展
3M 高可用架构 一.MMM 1. MMM的概述 MMM(Master-Master replication manager for MySQL,MySQL主主复制管理器)是一套支持双主故障切换和双主 ...
- 【NetCore】依赖注入的一些理解与分享
依赖注入 DI 前言 声明:我是一个菜鸟,此文是自己的理解,可能正确,可能有误.仅供学习参考帮助理解,如果直接拷贝代码使用造成损失概不负责. 相关的文章很多,我就仅在代码层面描述我所理解的依赖注入是个 ...
- matlab构建栅格地图绘图思路
matlab构建栅格地图绘图思路 近来因研究需要,调研并思考了栅格地图的生成方法,暂时总结以备不时之需. 栅格的建立最需要注意栅格粒度的问题,即根据需要调整栅格的边长,目前有两种思路一种是固定栅格边长 ...
- LeetCode随缘刷题之最长回文子串
这一题我用的相对比较笨的方法. 相对于大佬们用的动态规划法,比较复杂.但却更容易理解,我主要是通过记录下标来确定最长回文串的. package leetcode.day_12_06; /** * 给你 ...
- 赠送4本《 PHP 程序员面试笔试宝典》
< PHP 程序员面试笔试宝典>历时一年,由机械工业出版社出版,在 2018 年 11 月问世.全书共八个章节,涉及 面试笔试经验技巧.PHP 基础知识.PHP 进阶知识,PHP 面向对象 ...
- Deformable Templates For Eye Detection
1 Abstract This approach was published On "Deformable Templates for Face Recognition" by A ...
- Solution -「CF 487E」Tourists
\(\mathcal{Description}\) Link. 维护一个 \(n\) 个点 \(m\) 条边的简单无向连通图,点有点权.\(q\) 次操作: 修改单点点权. 询问两点所有可能路 ...