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或 ...
随机推荐
- Redis源码简要分析
转载请注明来源:https://www.cnblogs.com/hookjc/ 把所有服务端文件列出来,并且标示出其作用:adlist.c //双向链表ae.c //事件驱动ae_epoll.c // ...
- js _proto_和prototype 区别 剖析
首先,要明确几个点: 1.在JS里,万物皆对象.方法(Function)是对象,方法的原型(Function.prototype)是对象.因此,它们都会具有对象共有的特点. 即:对象具有属性__pro ...
- LNMP平台的redis对接安装
LNMP平台的redis对接安装 目录 LNMP平台的redis对接安装 一.安装LNMP的各个组件 二.安装redis服务 三.安装redis扩展 四.修改php配置文件 五.测试连接 一.安装LN ...
- 警惕!Python 中少为人知的 10 个安全陷阱!
作者:Dennis Brinkrolf 译者:豌豆花下猫@Python猫 原题:10 Unknown Security Pitfalls for Python 英文:https://blog.sona ...
- MySQL5.7 库、表结构、表字段的查询、更改操作
1.查询所有数据库 SHOW DATABASES; 2.查询库中所有表 写法1: ① USE [DATABASE_NAME]; ② SHOW TABLES; 写法2: SHOW TABLES FROM ...
- 手写RPC框架(六)整合Netty
手写RPC框架(六)整合Netty Netty简介: Netty是一个基于NIO的,提供异步,事件驱动的网络应用工具,具有高性能高可靠性等特点. 使用传统的Socket来进行网络通信,服务端每一个连接 ...
- Python中模块、类、函数、实例调用案例
19 a = '我是模块中的变量a' 20 21 def hi(): 22 a = '我是函数里的变量a' 23 print('函数"hi"已经运行!') 24 25 class ...
- java 人机猜拳 游戏
人机猜拳-游戏 掌握类和对象的使用,掌握方法的定义和返回值,掌握封装的运用 定义一个电脑类:Computer.java 点击查看[Computer.java]代码 /** * @Title: 电脑类 ...
- 【C# 线程】WaitHandle类
理论 Windows的线程同步方式可分为2种,用户模式构造和内核模式构造.内核模式构造:是由Windows系统本身使用,内核对象进行调度协助的.内核对象是系统地址空间中的一个内存块,由系统创建维护. ...
- CSC.exe编译器使用
如何用CSC.exe来编译Visual C#的代码文件 Visual C#是微软公司推出的新一代程序开发语言,Visual C#是微软公司.Net FrameWork框架中的一个重要的组成部分,也是微 ...