51nod 1594 Gcd and Phi 反演
Posted jackpei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 1594 Gcd and Phi 反演相关的知识,希望对你有一定的参考价值。
OTZ 又被吊打了。。。我当初学的都去哪了???
思路:反演套路?
提交:\(1\)次
题解:
求\(\sum_i=1^n\sum_j=1^n\varphi(gcd(\varphi(i),\varphi(j)))\)
设\(c[i]=\sum_j=1^n[\varphi(j)==i]\)
有:
\(\sum_i=1^n\sum_j=1^n\varphi(gcd(i,j))*c[i]*c[j]\)
欧拉反演一下,把\(gcd\)扔出来
\(\sum_i=1^n\sum_j=1^n\sum_d|gcd(i,j)\varphi(d)*c[i]*c[j]*[gcd(i,j)==d]\)
$\sum_d=1^n\varphi(d) \sum_i=1^\lfloor \fracnd \rfloor?\sum_j=1^\lfloor \fracnd \rfloor c[i*d] * c[j*d] * [gcd(i,j)==1] $
$\sum_d=1^n\varphi(d) \sum_i=1^\lfloor \fracnd \rfloorc[i*d] \sum_j=1^\lfloor \fracnd \rfloorc[j*d] ? [gcd(i,j)==1] $
\(\sum_d=1^n\varphi(d) \sum_i=1^\lfloor \fracnd \rfloorc[i*d] \sum_j=1^\lfloor \fracnd \rfloorc[j*d] \sum_k|gcd(i,j) \mu(k)\)
\(\sum_d=1^n\varphi(d) \sum_k=1^\lfloor \fracnd \rfloor \mu(k) \sum_i=1^\lfloor \fracnd*k \rfloorc[i*d*k] \sum_j=1^\lfloor \fracnd*k \rfloorc[j*d*k]\)
设\(s[i]=\sum_j=1^\lfloor \fracni \rfloor\ c[i*j]\),注意到\(s[i]\)可以在\(O(nlogn)\)计算出来
\(\sum_d=1^n\ \varphi(d) \sum_k=1^\lfloor \fracnd \rfloor \mu(k)\ s[d*k]^2\)
交换一下\(d\)与\(k\),可以优化枚举(见代码)
\(\sum_d=1^n\ \mu(d) \sum_k=1^\lfloor \fracnd \rfloor \varphi(k)\ s[d*k]^2\)
#include<cstdio>
#include<iostream>
#include<cstring>
#define ll long long
#define R register ll
using namespace std;
namespace Luitaryi
template<class I> inline I g(I& x) x=0;
register I f=1; register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f;
const int N=2e6;
int T,n,cnt,p[N>>1],phi[N+10],mu[N+10],c[N+10];
ll s[N+10],ans; bool v[N+10];
inline void PRE() phi[1]=mu[1]=1;
for(R i=2;i<=N;++i)
if(!v[i]) p[++cnt]=i,phi[i]=i-1,mu[i]=-1;
for(R j=1;j<=cnt&&i*p[j]<=N;++j)
v[i*p[j]]=true;
if(i%p[j]==0)
phi[i*p[j]]=phi[i]*p[j];
break;
phi[i*p[j]]=phi[i]*(p[j]-1);
mu[i*p[j]]=-mu[i];
inline void calc(int n) ans=0;
memset(c,0,sizeof(c)),memset(s,0,sizeof(s));
for(R i=1;i<=n;++i) ++c[phi[i]];
for(R i=1;i<=n;++i) for(R j=1,lim=n/i;j<=lim;++j) s[i]+=c[i*j];
for(R d=1;d<=n;++d) if(mu[d]) for(R k=1,lim=n/d;k<=lim;++k) //if(mu[d]) 优化枚举
ans+=mu[d]*phi[k]*s[d*k]*s[d*k];
inline void main() g(T); PRE(); while(T--) g(n),calc(n),printf("%lld\n",ans);
signed main() Luitaryi::main(); return 0;
2019.08.11
89
以上是关于51nod 1594 Gcd and Phi 反演的主要内容,如果未能解决你的问题,请参考以下文章