codeforces 809E Surprise me!
Tired of boring dates, Leha and Noora decided to play a game.
Leha found a tree with n vertices numbered from 1 to n. We remind you that tree is an undirected graph without cycles. Each vertex v of a tree has a number av written on it. Quite by accident it turned out that all values written on vertices are distinct and are natural numbers between 1 and n.
The game goes in the following way. Noora chooses some vertex u of a tree uniformly at random and passes a move to Leha. Leha, in his turn, chooses (also uniformly at random) some vertex v from remaining vertices of a tree (v ≠ u). As you could guess there are n(n - 1) variants of choosing vertices by players. After that players calculate the value of a function f(u, v) = φ(au·av) · d(u, v) of the chosen vertices where φ(x) is Euler's totient function and d(x, y) is the shortest distance between vertices x and y in a tree.
Soon the game became boring for Noora, so Leha decided to defuse the situation and calculate expected value of function f over all variants of choosing vertices u and v, hoping of at least somehow surprise the girl.
Leha asks for your help in calculating this expected value. Let this value be representable in the form of an irreducible fraction . To further surprise Noora, he wants to name her the value .
Help Leha!
The first line of input contains one integer number n (2 ≤ n ≤ 2·105) — number of vertices in a tree.
The second line contains n different numbers a1, a2, ..., an (1 ≤ ai ≤ n) separated by spaces, denoting the values written on a tree vertices.
Each of the next n - 1 lines contains two integer numbers x and y (1 ≤ x, y ≤ n), describing the next edge of a tree. It is guaranteed that this set of edges describes a tree.
In a single line print a number equal to P·Q - 1 modulo 109 + 7.
3
1 2 3
1 2
2 3
333333338
5
5 4 3 1 2
3 5
1 2
4 3
2 5
8
Euler's totient function φ(n) is the number of such i that 1 ≤ i ≤ n,and gcd(i, n) = 1, where gcd(x, y) is the greatest common divisor of numbers x and y.
There are 6 variants of choosing vertices by Leha and Noora in the first testcase:
- u = 1, v = 2, f(1, 2) = φ(a1·a2)·d(1, 2) = φ(1·2)·1 = φ(2) = 1
- u = 2, v = 1, f(2, 1) = f(1, 2) = 1
- u = 1, v = 3, f(1, 3) = φ(a1·a3)·d(1, 3) = φ(1·3)·2 = 2φ(3) = 4
- u = 3, v = 1, f(3, 1) = f(1, 3) = 4
- u = 2, v = 3, f(2, 3) = φ(a2·a3)·d(2, 3) = φ(2·3)·1 = φ(6) = 2
- u = 3, v = 2, f(3, 2) = f(2, 3) = 2
Expected value equals to . The value Leha wants to name Noora is 7·3 - 1 = 7·333333336 = 333333338 .
In the second testcase expected value equals to , so Leha will have to surprise Hoora by number 8·1 - 1 = 8 .
$\varphi(a_i*a_j)=\frac{\varphi(a_i)\varphi(a_j)gcd(a_i,a_j)}{\varphi(gcd(a_i,a_j))}$
$\sum_{d=1}^{n}\frac{d}{\varphi(d)}\sum_{i=1}^{n}\sum_{j=1}^{n}\varphi(a_i)\varphi(a_j)dist(i,j)[gcd(a_i,a_j)=d]$
$f(d)=\sum_{i=1}^{n}\sum_{j=1}^{n}\varphi(a_i)\varphi(a_j)dist(i,j)[gcd(a_i,a_j)=d]$
$g(d)=\sum_{i=1}^{n}\sum_{j=1}^{n}\varphi(a_i)\varphi(a_j)dist(i,j)[d|gcd(a_i,a_j)]$
$g(d)=\sum_{d|x}^{n}f(x)$
$f(d)=\sum_{d|x}^{n}\mu(\frac{x}{d})g(x)$
$f(d)=\sum_{i=1}^{\frac{n}{d}}\mu(i)g(id)$
$ans=\sum_{d=1}^{n}\frac{d}{\varphi(d)}\sum_{i=1}^{\frac{n}{d}}\mu(i)g(id)$
令$T=id$
$ans=\sum_{T=1}^{n}g(T)\sum_{d|T}\mu(\frac{T}{d})\frac{d}{\varphi(d)}$
令$h(T)=\sum_{d|T}\mu(\frac{T}{d})\frac{d}{\varphi(d)}$
对于g(d)有
$g(d)=\sum_{i=1且d|a_i}^{n}\sum_{j=1 且d|a_j}^{n}\varphi(a_i)\varphi(a_j)(dep_i+dep_j-2*dep_lca)$
$g(d)=\sum_{i=1且d|a_i}^{n}\varphi(a_i)*2*dep_i\sum_{j=1 且d|a_j}^{n}\varphi(a_j)-2*\sum_{i=1且d|a_i}^{n}\sum_{j=1 且d|a_j}^{n}\varphi(a_i)\varphi(a_j)*dep_lca$
$\sum_{i=1且d|a_i}^{n}\varphi(a_i)*2*dep_i\sum_{j=1且d|a_j}^{n}\varphi(a_j)=2*\sum_{i=1且d|a_i}^{n}\varphi(a_i)*dep_i*Sum$
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long lol;
struct Node
{
int next,to;
}edge[],edge2[];
int num,head[],head2[],mu[],phi[],vis[],inv[],Mod=1e9+;
int n,tot,prime[],h[],dep[],fa[][],dfn[],cnt,size[],st[];
int bin[],ed[],flag[],ans,a[],sum,f[],l[],b[],top,g[];
int id[];
bool cmp(int a,int b)
{
return dfn[a]<dfn[b];
}
void add(int u,int v)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
}
void add2(int u,int v)
{
num++;
edge2[num].next=head2[u];
head2[u]=num;
edge2[num].to=v;
}
int qpow(int x,int y)
{
int res=;
while (y)
{
if (y&) res=1ll*res*x%Mod;
x=1ll*x*x%Mod;
y>>=;
}
return res;
}
void prework()
{int i,j;
mu[]=phi[]=;
inv[]=;
for (i=;i<=n;i++)
inv[i]=1ll*(Mod-Mod/i)*inv[Mod%i]%Mod;
for (i=;i<=n;i++)
{
if (vis[i]==)
{
++tot;
prime[tot]=i;
mu[i]=-;
phi[i]=i-;
}
for (j=;j<=tot;j++)
{
if (1ll*i*prime[j]>n) break;
vis[i*prime[j]]=;
if (i%prime[j]==)
{
phi[i*prime[j]]=1ll*phi[i]*prime[j];
break;
}
else
{
phi[i*prime[j]]=1ll*phi[i]*(prime[j]-);
mu[i*prime[j]]=-mu[i];
}
}
}
for (i=;i<=n;i++)
{
for (j=;j<=n&&1ll*i*j<=n;j++)
{
h[i*j]+=1ll*mu[j]*i%Mod*inv[phi[i]]%Mod;
h[i*j]%=Mod;
}
}
}
int lca(int x,int y)
{int i;
if (dep[x]<dep[y]) swap(x,y);
for (i=;i>=;i--)
if (dep[fa[x][i]]>=dep[y])
x=fa[x][i];
if (x==y) return x;
for (i=;i>=;i--)
{
if (fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][];
}
int get_dis(int x,int y)
{
return dep[x]+dep[y]-*dep[lca(x,y)];
}
void dfs(int x,int pa)
{int i;
dep[x]=dep[pa]+;
dfn[x]=++cnt;
size[x]=;
for (i=;bin[i]<=dep[x];i++)
fa[x][i]=fa[fa[x][i-]][i-];
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v==pa) continue;
fa[v][]=x;
dfs(v,x);
size[x]+=size[v];
}
ed[x]=cnt;
}
int DP(int x)
{
int s1=,s2=;
if (flag[x])
{
ans+=2ll*phi[a[x]]%Mod*sum%Mod*dep[x]%Mod;
ans%=Mod;
f[x]=phi[a[x]];
s1=1ll*f[x]*f[x]%Mod*dep[x]%Mod;
}
else f[x]=;
for (int i=head2[x];i;i=edge2[i].next)
{
int v=edge2[i].to;
DP(v);
s2=(s2+1ll*f[x]*f[v]%Mod*dep[x]%Mod)%Mod;
f[x]=(f[x]+f[v])%Mod;
}
ans=((ans-4ll*s2%Mod)%Mod-2ll*s1%Mod)%Mod;
ans=(ans+Mod)%Mod;
}
void solve(int x)
{int i,Lca;
int tot=;sum=;
for (i=x;i<=n;i+=x)
flag[l[++tot]=id[i]]=,b[tot]=l[tot],sum=(sum+phi[i])%Mod;
sort(l+,l+tot+,cmp);
Lca=l[];
for (i=;i<=tot;i++)
if (ed[l[i-]]<dfn[l[i]]) l[++tot]=lca(l[i],l[i-]),Lca=lca(Lca,l[i]);
l[++tot]=Lca;
sort(l+,l+tot+,cmp);
tot=unique(l+,l+tot+)-l-;
top=;num=;ans=;
st[++top]=Lca;
for (i=;i<=tot;i++)
{
while (top&&ed[st[top]]<dfn[l[i]]) top--;
add2(st[top],l[i]);
//cout<<x<<' '<<st[top]<<' '<<l[i]<<endl;
st[++top]=l[i];
}
DP(Lca);
g[x]=ans%Mod;
for (i=;i<=tot;i++) flag[l[i]]=,head2[l[i]]=;
}
int main()
{int i,j,u,v;
cin>>n;
bin[]=;
for (i=;i<=;i++)
bin[i]=bin[i-]*;
prework();
for (i=;i<=n;i++)
{
scanf("%d",&a[i]);
id[a[i]]=i;
}
for (i=;i<=n-;i++)
{
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(,);
for (i=;i<=n;i++)
solve(i);
ans=;
for (i=;i<=n;i++)
ans=(ans+1ll*g[i]*h[i]%Mod)%Mod;
ans=1ll*ans*qpow(n-,Mod-)%Mod*qpow(n,Mod-)%Mod;
cout<<(ans+Mod)%Mod;
}
$\varphi(a_i*a_j)=\frac{\varphi(a_i)\varphi(a_j)gcd(a_i,a_j)}{\varphi(gcd(a_i,a_j))}$
$\sum_{d=1}^{n}\frac{d}{\varphi(d)}\sum_{i=1}^{n}\sum_{j=1}^{n}\varphi(a_i)\varphi(a_j)dist(i,j)[gcd(a_i,a_j)=d]$
$f(d)=\sum_{i=1}^{n}\sum_{j=1}^{n}\varphi(a_i)\varphi(a_j)dist(i,j)[gcd(a_i,a_j)=d]$
$g(d)=\sum_{i=1}^{n}\sum_{j=1}^{n}\varphi(a_i)\varphi(a_j)dist(i,j)[d|gcd(a_i,a_j)]$
$g(d)=\sum_{d|x}^{n}f(x)$
$f(d)=\sum_{d|x}^{n}\mu(\frac{x}{d})g(x)$
$f(d)=\sum_{i=1}^{\frac{n}{d}}\mu(i)g(id)$
$ans=\sum_{d=1}^{n}\frac{d}{\varphi(d)}\sum_{i=1}^{\frac{n}{d}}\mu(i)g(id)$
令$T=id$
$ans=\sum_{T=1}^{n}g(T)\sum_{d|T}\mu(\frac{T}{d})\frac{d}{\varphi(d)}$
令$h(T)=\sum_{d|T}\mu(\frac{T}{d})\frac{d}{\varphi(d)}$
对于g(d)有
$g(d)=\sum_{i=1且d|a_i}^{n}\sum_{j=1 且d|a_j}^{n}\varphi(a_i)\varphi(a_j)(dep_i+dep_j-2*dep_lca)$
$g(d)=\sum_{i=1且d|a_i}^{n}\varphi(a_i)*2*dep_i\sum_{j=1 且d|a_j}^{n}\varphi(a_j)-2*\sum_{i=1且d|a_i}^{n}\sum_{j=1 且d|a_j}^{n}\varphi(a_i)\varphi(a_j)*dep_lca$
$\sum_{i=1且d|a_i}^{n}\varphi(a_i)*2*dep_i\sum_{j=1且d|a_j}^{n}\varphi(a_j)=2*\sum_{i=1且d|a_i}^{n}\varphi(a_i)*dep_i*Sum$
codeforces 809E Surprise me!的更多相关文章
- Codeforces 809E Surprise me! [莫比乌斯反演]
洛谷 Codeforces 非常套路的一道题,很适合我在陷入低谷时提升信心-- 思路 显然我们需要大力推式子. 设\(p_{a_i}=i\),则有 \[ \begin{align*} n(n-1)an ...
- Codeforces 809E - Surprise me!(虚树+莫比乌斯反演)
Codeforces 题目传送门 & 洛谷题目传送门 1A,就 nm 爽( 首先此题一个很棘手的地方在于贡献的计算式中涉及 \(\varphi(a_ia_j)\),而这东西与 \(i,j\) ...
- Codeforces.809E.Surprise me!(莫比乌斯反演 虚树)
题目链接 \(Description\) 给定一棵树,求\[\frac{1}{n(n-1)/2}\times\sum_{i\in[1,n],j\in[1,n],i\neq j}\varphi(a_i\ ...
- 【Codeforces 809E】Surprise me!(莫比乌斯反演 & 虚树)
Description 给定一颗 \(n\) 个顶点的树,顶点 \(i\) 的权值为 \(a_i\).求: \[\frac{1}{n(n-1)}\sum_{i=1}^n\sum_{j=1}^n\var ...
- Codeforces Round #415 (Div. 1) (CDE)
1. CF 809C Find a car 大意: 给定一个$1e9\times 1e9$的矩阵$a$, $a_{i,j}$为它正上方和正左方未出现过的最小数, 每个询问求一个矩形内的和. 可以发现$ ...
- Codeforces Round #277.5 (Div. 2)
题目链接:http://codeforces.com/contest/489 A:SwapSort In this problem your goal is to sort an array cons ...
- Codeforces Beta Round #51 B. Smallest number dfs
B. Smallest number Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/55/pro ...
- 【CF809E】Surprise me!(动态规划,虚树,莫比乌斯反演)
[CF809E]Surprise me!(动态规划,虚树,莫比乌斯反演) 题面 洛谷 CodeForces 翻译: 给定一棵\(n\)个节点的树,每个点有一个权值\(a[i]\),保证\(a[i]\) ...
- Codeforces 915 E Physical Education Lessons
题目描述 This year Alex has finished school, and now he is a first-year student of Berland State Univers ...
随机推荐
- JavaScript判断类型
1.typeof操作符,返回值为字符串,用来判断一个值是哪种基本类型 "undefined"-Undefined "boolean"-Boolean " ...
- 论C++的智能指针
一.简介 参考这篇博客,并且根据<C++ Primer>中相关知识,我总结了C++关于智能指针方面的内容. 为了解决内存泄漏的问题,便出现了智能指针.STL提供的智能指针有:aut ...
- Alpha冲刺Day4
Alpha冲刺Day4 一:站立式会议 今日安排: 我们把项目大体分为四个模块:数据管理员.企业人员.第三方机构.政府人员.完成了数据库管理员模块.因企业人员与第三方人员模块存在大量的一致性,故我们团 ...
- python array 使用创建10万浮点数
from array import array from random floats = array('d',random((for i in range(10**7)) fp = open('flo ...
- 库函数atoi
函数名:atoi 功能: 把一个字符串转换成一个整数. 看似简单,主要是情况太多,需要注意考虑. 测试代码: Test(NULL); Test(""); Test("12 ...
- Python choice() 函数
Python choice() 函数 Python 数字 描述 choice() 方法返回一个列表,元组或字符串的随机项. 语法 以下是 choice() 方法的语法: import random ...
- Tornado 用户身份验证框架
1.安全cookie机制 import tornado.web session_id = 1 class MainHandler(tornado.web.RequestHandler): def ge ...
- linux服务器操作系统,在相同环境下,哪个做lamp服务器更稳定点?哪个版本更稳定?
随着国内WEB服务越来越多,如何才能选择一个合适的linux服务器操作系统?在国内用的最多的好像是红帽子系列也就是red hat系列,但有些版本缺乏稳定性.新手在选择操作系统的时候最好只用偶数版本,还 ...
- Raid 5数据恢复原理以及raid 5数据恢复实际操作案例
Raid 5数据恢复算法原理 要理解 raid 5数据恢复原理首先要先认识raid5,"分布式奇偶校验的独立磁盘结构"也就是我们称之为的raid 5数据恢复有一个概念需要理解,也就 ...
- nyoj 寻找最大数(二)
寻找最大数(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 给你一个数字n(可能有前缀0). 要求从高位到低位,进行 进栈出栈 操作,是最后输出的结果最大. ...