mcfx's blog - 2017年5月
/2017/05/
个人博客,(曾经)基本只放题解,现在随便写点啥了吧(
-
Codeforces 809E. Surprise me!
/archives/236/
2017-05-25T20:24:07+08:00
###Description
给一棵树,每个点点权 $$a_i$$,保证 $$a_i$$各不相同,现在随机选两个点 $$u,v$$,求 $$f(u,v)=\phi(a_u\cdot a_v)\cdot dis(u,v)$$ 的期望,$$mod\ 10^9+7$$。
链接:[http://codeforces.com/contest/809/problem/E](http://codeforces.com/contest/809/problem/E "http://codeforces.com/contest/809/problem/E")
###Solution
首先,有一个结论:$$\phi(a\cdot b)=\frac{\phi(a)\cdot\phi(b)\cdot g}{\phi(g)},g=gcd(a,b)$$
证明:考虑找一个 $$x$$,使得 $$x|b,gcd(\frac{b}{x},a)=1,gcd(x,\frac{b}{x})=1$$ 且 $$a$$ 包含 $$x$$ 中所有质因子。
那么 $$\phi(a\cdot b)=\phi(a)\cdot x\cdot\phi(\frac{b}{x})=\frac{\phi(a)\cdot\phi(b)\cdot x}{\phi(x)}$$
显然,$$x$$ 是 $$g$$ 的倍数,所以 $$\frac{x}{g}=\frac{\phi(x)}{\phi(g)}$$,所以$$\phi(a\cdot b)=\frac{\phi(a)\cdot\phi(b)\cdot g}{\phi(g)}$$
有了这个结论之后可以考虑点分,那么设 $$dis(x)$$ 表示 $$x$$ 到当前根的距离。
设 $$h(x)=\frac{x}{\phi(x)}$$,那么$$f(u,v)=\phi(a_u)\cdot\phi(a_v)\cdot h(g)\cdot(dis(u)+dis(v)),g=gcd(a_u,a_v)$$
考虑当 $$u$$ 确定时,需要知道 $$\sum\phi(a_v)\cdot h(gcd(a_u,a_v))$$ 和 $$\sum\phi(a_v)\cdot h(gcd(a_u,a_v))\cdot dis(v)$$。
设 $$g(x)=h(x)-\sum[y|x,y\neq x]g(y)$$,那么 $$h(gcd(a_u,a_v))=\sum[x|a_u,x|a_v]g(x)$$
这样就可以直接枚举约数算贡献了。
###Code
```c++
#include
typedef long long ll;
inline void repr(int&a,int b){if(ato,x);
sz[x]+=sz[i->to];
}
}
inline void dfs2(int x,int fa)
{
int t=rsz-sz[x];
for(edge*i=p[x];i;i=i->ne)
if(i->to!=fa&&!vis[i->to])
{
repr(t,sz[i->to]);
dfs2(i->to,x);
}
if(tne)
if(i->to!=fa&&!vis[i->to])
dfs3(i->to,x,dis+1);
}
inline void dfs4(int x,int fa,int dis)
{
int a=phi[w[x]],b=(ll)a*dis%P,A,B;
foe(i,v[w[x]])
{
get(*i,A,B);
ans=(ans+(ll)a*B+(ll)b*A)%P;
}
for(edge*i=p[x];i;i=i->ne)
if(i->to!=fa&&!vis[i->to])
dfs4(i->to,x,dis+1);
}
inline void work(int x)
{
dfs1(x,0);
rsz=nsz=sz[x],nro=x;
dfs2(x,0);
vis[x=nro]=1;
foe(i,v[w[x]])set(*i,phi[w[x]],0);
for(edge*i=p[x];i;i=i->ne)
if(!vis[i->to])
{
dfs4(i->to,x,1);
dfs3(i->to,x,1);
}
fo0(i,qe)g[q[i]]=h[q[i]]=-1;
qe=0;
for(edge*i=p[x];i;i=i->ne)
if(!vis[i->to])work(i->to);
}
int main()
{
fo1(i,N-1)for(int j=i;j