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或 ...
随机推荐
- Java高质量博文链接集合
1. 看完这个,Java IO从此不在难 https://www.jianshu.com/p/715659e4775f 2. Java 8 中的 Streams API 详解 https://www. ...
- web虚拟主机、日志分割以及日志分析
目录 一.构建虚拟web主机 1.1 概述 1.2 支持的虚拟主机类型 1.3 部署虚拟主机步骤 1.3.1 基于域名的虚拟主机 (1)为虚拟主机提供域名解析 (2)为虚拟主机准备网页文档 (3)添加 ...
- 你还不懂java的日志系统吗
一.背景 在java的开发中,使用最多也绕不过去的一个话题就是日志,在程序中除了业务代码外,使用最多的就是打印日志.经常听到的这样一句话就是"打个日志调试下",没错在日常的开发.调 ...
- Charles抓包工具介绍
1.Charles是什么? Charles是一款基于http协议的代理服务器,通过称为电脑或者浏览器的代理,然后截取请求和请求结果达到分析抓包的目的. 2.Charles有哪些用途? (1)能够分析前 ...
- suse 12 二进制部署 Kubernetets 1.19.7 - 第07章 - 部署kube-controller-manager组件
文章目录 1.7.部署kube-controller-manager 1.7.0.创建kube-controller-manager请求证书 1.7.1.生成kube-controller-manag ...
- Dubbo基础之四管理控制台 dubbo-admin
Dubbo提供一个重要功能就是服务治理(SOA governance),什么是服务治理呢?企业为了确保项目顺利完成而实施的过程,需要进行各方面的管理.服务治理就是用来管理SOA的采用和实现的过程. 服 ...
- dart系列之:集合使用最佳实践
目录 简介 使用字面量创建集合 不要使用.length来判断集合是否为空 可遍历对象的遍历 List.from和iterable.toList where和whereType 避免使用cast 总结 ...
- CentOS7安装及配置 Zabbix全步骤,超详细教程
服务器太多,还在不同的平台和账户,监控不便 整个 Zabbix 监控,开始吧 一.关闭防火墙并开机不启动 sudo setenforce 0 sudo sed -i "s/SELINUX=e ...
- oracle数据库表导出
寻找一个测试table,清空,将需要导出的表导入表中的任意一列,写导出语句,导出. EXPDP USERID='user/account@orcl11 as sysdba' schemas=temp ...
- 【基础篇】js对本地文件增删改查--改
前置条件: 1. 本地有安装node,点击传送门 项目目录: 1. msg.json内容 { "data": [ { "id": 1, "name&q ...