bzoj 2820(Mobius)

来源:互联网 发布:ubuntu查找java路径 编辑:程序博客网 时间:2024/06/03 13:06

传送门
一道没有真正意义上进行反演的“反演” 题。
这里写图片描述

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>using namespace std;typedef long long ll;const int MAXN=1e7+2;bool vis[MAXN];int prime[MAXN/10],mu[MAXN],num=0,n,m;ll f[MAXN];inline int read() {    int x=0;char c=getchar();    while (c<'0'||c>'9') c=getchar();    while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();    return x;}inline void linear_shaker() {    mu[1]=1,f[1]=0;    memset(vis,false,sizeof(vis));    for (register int i=2;i<MAXN;++i) {        if (!vis[i]) prime[++num]=i,mu[i]=-1;        for (int j=1;j<=num&&i*prime[j]<MAXN;++j) {            vis[i*prime[j]]=true;            if (i%prime[j]==0) {mu[i*prime[j]]=0;break;}            mu[i*prime[j]]=-mu[i];        }    }    for (int i=1;i<=num;++i)        for (int j=1;j<=MAXN&&j*prime[i]<MAXN;++j)            f[j*prime[i]]+=mu[j];    for (register int i=2;i<MAXN;++i) f[i]+=f[i-1];}inline ll cal(int n,int m) {    ll ans=0;    int t=min(n,m),last;    for (int i=1;i<=t;i=last+1) {        last=min(n/(n/i),m/(m/i));        ans+=(f[last]-f[i-1])*(n/i)*(m/i);    }    return ans;}int main() {//  freopen("bzoj 2820.in","r",stdin);    int kase=read();    linear_shaker();    while (kase--) {        n=read(),m=read();        printf("%lld\n",cal(n,m));    }    return 0;} 
原创粉丝点击