CF809E Surprise me!
题解:
一道很套路的题目
首先一个结论
$\phi(xy)=\frac{\phi(x)*\phi(y)*gcd(x,y)}{\phi(gcd(x,y))}$
这个按照$\phi$的定义很容易知道
然后我们可以枚举gcd,很套路的可以莫比乌斯反演
然后变成给出k个点,求他们$\phi(x)*\phi(y)*dis(x,y)$
考虑所以gcd的点数为$\frac{n}{1}+\frac{n}{2}+\frac{n}{3}$=$nlogn$
于是我们需要一个与点数相关的算法
考虑虚树
之后有两种办法解决$\phi(x)*\phi(y)*dis(x,y)$
一种是考虑一个节点和它儿子节点的关系,那么就处理一下子树信息就行了
一种是把$dis(x,y)$写成$dis(x)+dis(y)-2*dis(lca(x,y))$然后dp一下
代码:
#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for (int i=h;i<=t;i++)
#define dep(i,t,h) for (int i=t;i>=h;i--)
#define ll long long
const int N=5e5;
const int mo=1e9+;
int a[N],head[N],dfn[N],cnt,p[N],pos[N],q[N],bz[][N],dep[N];
int f[N],phi[N],pri[N],prinum,ispri[N],n,l,miu[N],inv2;
bool tt[N];
struct re{
int a,b,c;
}e[N*];
int fsp(int x,int y)
{
ll ans=;
while (y)
{
if (y&) ans=ans*x%mo;
x=1ll*x*x%mo; y>>=;
}
return ans;
}
IL void plu(int &x,int y)
{
x=(x+y)%mo;
}
IL void arr(int x,int y)
{
e[++l].a=head[x];
e[l].b=y;
head[x]=l;
}
void dfs(int x,int y)
{
dfn[x]=++cnt; bz[][x]=y; dep[x]=dep[y]+;
for (rint u=head[x];u;u=e[u].a)
{
int v=e[u].b;
if (v!=y) dfs(v,x);
}
}
bool cmp(int x,int y)
{
return dfn[x]<dfn[y];
}
int lca(int x,int y)
{
if (dep[x]<dep[y]) swap(x,y);
dep(i,,) if (dep[bz[i][x]]>=dep[y]) x=bz[i][x];
if (x==y) return x;
dep(i,,) if (bz[i][x]!=bz[i][y]) x=bz[i][x],y=bz[i][y];
return bz[][x];
}
ll pp;
struct E{
int l,head[N],ans[N];
re e[N*];
IL void arr(int x,int y)
{
e[++l].a=head[x];
e[l].b=y;
e[l].c=x;
head[x]=l;
}
IL void clear()
{
rep(i,,l) head[e[i].c]=;
l=;
}
void dfs(int x)
{
ans[x]=phi[a[x]];
if (!tt[x])
{
ans[x]=;
}
ll ans2=;
for (rint u=head[x];u;u=e[u].a)
{
int v=e[u].b;
dfs(v);
ans[x]=(ans[x]+ans[v])%mo;
ans2+=1ll*ans[v]*ans[v];
}
ans2=(1ll*ans[x]*ans[x]-ans2)%mo;
pp=(pp+*dep[x]*ans2)%mo;
}
}E;
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n;
rep(i,,n) cin>>a[i],pos[a[i]]=i;
rep(i,,n-)
{
int x,y;
cin>>x>>y;
arr(x,y); arr(y,x);
}
dfs(,);
rep(i,,)
rep(j,,n)
bz[i][j]=bz[i-][bz[i-][j]];
miu[]=; phi[]=;
rep(i,,n)
{
if (!ispri[i]) {pri[++prinum]=i; miu[i]=-; phi[i]=i-;}
for (int j=;j<=prinum&&pri[j]*i<=n;j++)
{
ispri[i*pri[j]]=;
if (i%pri[j]==)
{
miu[i*pri[j]]=;
phi[i*pri[j]]=phi[i]*pri[j];
break;
} else miu[i*pri[j]]=-miu[i],phi[i*pri[j]]=phi[i]*(pri[j]-);
}
}
rep(i,,n)
{
int num=;
int ans=;
ll ans2=;
for (int j=;j*i<=n;j++) p[++num]=pos[i*j],plu(ans,phi[i*j]);
rep(j,,num) ans2=(ans2+1ll*phi[i*j]*dep[p[j]])%mo;
ans2=2ll*ans2*ans%mo;
sort(p+,p+num+,cmp);
rep(i,,num) tt[p[i]]=;
int h=,t=; q[h]=;
rep(i,,num)
{
while (h<t&&dep[lca(p[i],q[t])]<=dep[q[t-]])
{
E.arr(q[t-],q[t]); t--;
}
int k=lca(p[i],q[t]);
if (k!=q[t])
{
E.arr(k,q[t]); q[t]=k;
}
if (q[t]!=p[i]) q[++t]=p[i];
}
while (h<t)
{
E.arr(q[t-],q[t]); t--;
}
pp=;
E.dfs();
ans2=((ans2-pp)%mo+mo)%mo;
f[i]=ans2;
E.clear();
rep(i,,num) tt[p[i]]=;
}
ll ans2=;
rep(k,,n)
{
int ans=;
for (int j=;j*k<=n;j++)
{
plu(ans,miu[j]*f[j*k]);
}
ans2=(ans2+1ll*k*ans%mo*fsp(phi[k],mo-))%mo;
}
cout<<ans2*fsp(n,mo-)%mo*fsp(n-,mo-)%mo<<endl;
return ;
}
CF809E Surprise me!的更多相关文章
- CF809E Surprise me!(莫比乌斯反演+Dp(乱搞?))
题目大意: 给你一棵树,树上的点编号为\(1-n\).选两个点\(i.j\),能得到的得分是\(\phi(a_i*a_j)*dis(i,j)\),其中\(dis(i,j)\)表示\(a\)到\(b\) ...
- CF809E Surprise me! 莫比乌斯反演、虚树
传送门 简化题意:给出一棵\(n\)个点的树,编号为\(1\)到\(n\),第\(i\)个点的点权为\(a_i\),保证序列\(a_i\)是一个\(1\)到\(n\)的排列,求 \[ \frac{1} ...
- 仙人掌 && 圆方树 && 虚树 总结
仙人掌 && 圆方树 && 虚树 总结 Part1 仙人掌 定义 仙人掌是满足以下两个限制的图: 图完全联通. 不存在一条边处在两个环中. 其中第二个限制让仙人掌的题做 ...
- 【CF809E】Surprise me!(动态规划,虚树,莫比乌斯反演)
[CF809E]Surprise me!(动态规划,虚树,莫比乌斯反演) 题面 洛谷 CodeForces 翻译: 给定一棵\(n\)个节点的树,每个点有一个权值\(a[i]\),保证\(a[i]\) ...
- 【CF809E】Surprise me! 树形DP 虚树 数学
题目大意 给你一棵\(n\)个点的树,每个点有权值\(a_i\),\(a\)为一个排列,求 \[ \frac{1}{n(n-1)}\sum_{i=1}^n\sum_{j=1}^n \varphi(a_ ...
- 【CF809E】Surprise me!
题目 这是一道神仙题 看到这样一个鬼畜的柿子 \[\sum_{i=1}^n\sum_{j=1}^n\varphi(a_i\times a_j)\times dis(i,j)\] 又是树上距离又是\(\ ...
- CF809E 【Surprise me!】
我们要求的柿子是张这样子的: \[\frac{1}{n * (n - 1)} * \sum_{i = 1}^n\sum_{j = 1}^{n}\phi(a_i*a_j)*dis(i, j)\] 其中\ ...
- Surprise团队项目总结
Surprise团队项目总结 项目实现情况 实现人人模式:2个用户在同一台电脑上进行切磋下棋,即实现五子棋游戏的基本功能 实现人机模式:初级模式已经实现,可以进行人机交互,但是还没达到智能判断下棋点 ...
- Surprise团队第四周项目总结
Surprise团队第四周项目总结 项目进展 这周我们小组的项目在上周的基础上进行了补充,主要注重在注册登录界面的改进优化与美观,以及关于人计算法的学习与初步实现. 我们小组针对上次APP中界面出现的 ...
随机推荐
- NOIP 2019 RP++
\[\huge NOIP^{2019}_{RP++}\] \[\huge NOIP^{2019}_{Score++}\]
- Linux安装gitbook
安装g++ 默认centos7上是没有安装g++ 通过命令: $ yum -y install gcc openssl-devel gcc-c++ compat-gcc-34 compat-gcc-3 ...
- VS配置Halcon(一次配置,永久使用)
[说明]只需配置一次,以后新项目无需再次配置. 本教程是64位版本,32位可参考本教程.VS与Halcon无论哪个版本,都可参考本教程. [步骤]以VS2015+Halcon18.11为例 1.新建一 ...
- python全栈开发中级班全程笔记(第二模块、第四章)(常用模块导入)
python全栈开发笔记第二模块 第四章 :常用模块(第二部分) 一.os 模块的 详解 1.os.getcwd() :得到当前工作目录,即当前python解释器所在目录路径 impor ...
- Guest Editors’ Introduction: Special Issue on Advances in Management of Softwarized Networks
文章名称:Guest Editors’ Introduction:Special Issue on Advances in Management of Softwarized Networks 发表时 ...
- axios传参
get //通过给定的ID来发送请求 axios.get('/user?ID=12345') .then(function(response){ console.log(response); }).c ...
- java eclipse中使用wsdl生成soap 的客户端代码
项目右键--> new --> other finish完成
- openssl实现自签名证书
前言 证书的作用 加密通信数据,验证对象身份,保证数据完整性 什么是自签名证书 公认的证书往往都需要收费,如果客户端与服务端都是由我们自己来操控,那便可以使用自签名证书(说白了就是只是自己认可的证书) ...
- CRMEB 商城系统常见错误修复办法
清空了用户表,没有清空拼团记录表导致,解决办法 --v2.5.2 清空拼团表-- TRUNCATE table eb_store_pink 修改了组合数据规则导致的,更新数据即可 --v2.5.2 e ...
- 使用Perfect Player观看电视直播
Perfect Player下载地址: 官网 http://niklabs.com/ 去广告版本:链接: https://pan.baidu.com/s/1gevIdBghB6lB46vVyfQUWg ...