hdu6134 Battlestation Operational 莫比乌斯反演

来源:互联网 发布:安卓系统编程入门pdf 编辑:程序博客网 时间:2024/06/14 21:27

题目:

f(n)=i=1nj=1iij[(i,j)=1],


where [(i,j)=1] evaluates to be 1 if gcd(i,j)=1, otherwise 0.

思路:

F[i]=i/1+i/2+...+i/i 向上取整

D[i]=i/1+i/2+...+i/i 向下取整

其中F[i]=D[i-1]+1D[i]=F[i]-i+cntcnti的因子的个数

然后就可以使用容斥定理了。

代码:

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<algorithm>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<list>#include<numeric>using namespace std;#define LL long long#define ULL unsigned long long#define INF 0x3f3f3f3f#define mm(a,b) memset(a,b,sizeof(a))#define PP puts("*********************");template<class T> T f_abs(T a){ return a > 0 ? a : -a; }template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; }template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}// 0x3f3f3f3f3f3f3f3f// 0x3f3f3f3fconst int MOD=1e9+7;const int maxn=1e6+50;bool check[maxn];int prime[maxn];int mu[maxn],sum[maxn];int F[maxn],D[maxn],ans[maxn];void Moblus(int n){    mm(check,false);    mu[1]=1;    int tot=0;    for(int i=2;i<=n;i++){        if(!check[i]){            prime[tot++]=i;            mu[i]=-1;        }        for(int j=0;j<tot;j++){            if(i*prime[j]>n)                break;            check[i*prime[j]]=true;            if(i%prime[j]==0){                mu[i*prime[j]]=0;                break;            }            else{                mu[i*prime[j]]=-mu[i];            }        }    }    F[1]=D[1]=1;    for(int i=2;i<=n;i++){        F[i]=D[i-1]+i;        int x=i,cnt=1;        for(int j=0;prime[j]*prime[j]<=i;j++){            int num=0;            while(x%prime[j]==0){                num++;                x/=prime[j];            }            cnt*=(num+1);        }        if(x>1) cnt*=2;        D[i]=F[i]-i+cnt;    }    for(int i=1;i<=n;i++) ans[i]=F[i];    for(int i=2;i<=n;i++){        for(int j=i;j<=n;j+=i)            ans[j]+=mu[i]*F[j/i];    }    for(int i=2;i<=n;i++){        ans[i]=(ans[i]+ans[i-1])%MOD;    }}int main(){    int n;    Moblus(maxn-5);    while(~scanf("%d",&n)){        printf("%d\n",ans[n]);    }    return 0;}


阅读全文
0 0
原创粉丝点击