您的位置:首页 > 其它

njust oj triple 莫比乌斯反演

2016-04-19 17:19 337 查看
分析:令f(x)为1到n的gcd(i,j)==x的个数

F(x)为1到n的x|gcd(i,j)的对数

显然F(n)=∑n|df(d)

然后由莫比乌斯反演可得f(n)=∑n|d μ(d/n)*F(d)

由题目显然可得,令cnt=n/x,当cnt<3时,F(x)为0,cnt>=3,F(x)=cnt*(cnt-1)*(cnt-2)/6

然后就是暴力,复杂度,O(T*n)

注:题目链接https://icpc.njust.edu.cn/Problem/Local/1923/

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
typedef long long LL;
const int N=1e5+5;
int n,m,T,prime
,mu
;
bool vis
;
void getmu()
{
mu[1] = 1;
int cnt = 0;
for(int i=2; i<=N-5; i++)
{
if(!vis[i])
{
prime[cnt++] = i;
mu[i] = -1;
}
for(int j=0; j<cnt&&i*prime[j]<=N-5; j++)
{
vis[i*prime[j]] = 1;
if(i%prime[j]) mu[i*prime[j]] = -mu[i];
else
{
mu[i*prime[j]] = 0;
break;
}
}
}
}
LL F(int x){
LL tmp=n/x;
if(tmp<3)return 0;
return tmp*(tmp-1)/2*(tmp-2)/3;
}
int main(){
getmu();
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
LL ans=0;
for(int i=1;i*m<=n;++i){
ans+=mu[i]*F(i*m);
}
printf("%lld\n",ans);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: