积性函数

来源:互联网 发布:登录windows账户和密码 编辑:程序博客网 时间:2024/06/05 22:56
积性函数:对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时f(ab)=f(a)f(b)
若对于某积性函数 f(n) ,就算a, b不互质,也有f(ab)=f(a)f(b),则称它为完全积性的
如果f是积性函数,那么其和是积性函数,其积也是积性函数
设有 , 那么其因子个数是 ,其因子和是
此外,欧拉函数,最大公约数gcd(a,b)=gcd(a1,b)*gcd(a2,b) [ a=a1a2 ],莫比乌斯函数 也是积性函数。

献上两题:
POJ 2992 Divisors
http://poj.org/problem?id=2992
大意:求解C(n,k)的约数和,其中0 ≤ k ≤ n ≤ 431。
不知道有多少数据,如果不预处理肯定是超时的。下面代码C++能过,但G++超时

#include <iostream>#include <cstdio>#include <cstring>using namespace std;typedef long long LL;const LL N=500,M=500;LL fac[N],cnt;bool vis[M];  // care: RELL p[N][N],pow1[N];void getfac(){    for(LL i=2;i<M;i++){        if(!vis[i]) fac[cnt++]=i;        for(LL j=0;j<cnt&&fac[j]*i<M;j++){            vis[fac[j]*i]=1;            if(i%fac[j]==0) break;        }    }}LL getpow(LL num,LL d){    LL ans=0;    while(num){        num=num/d;        ans=ans+num;    }    return ans;}int main(){    getfac();    for(LL i=0;i<=431;i++){        for(LL j=0;fac[j]<=i;j++){            p[i][fac[j]]=getpow(i,fac[j]);        }    }    LL n,k;    while(cin>>n>>k){        memset(pow1,0,sizeof(pow1));        for(LL i=0;fac[i]<=n;i++){            pow1[i]+=p[n][fac[i]];            pow1[i]-=p[k][fac[i]];            pow1[i]-=p[n-k][fac[i]];        }        LL ans=1;        for(LL i=0;fac[i]<=n;i++){            ans=ans*(pow1[i]+1);        }        printf("%lld\n",ans);    }    return 0;}

不过while部分可以这样写:
while(cin>>n>>k){        LL ans=1;        for(LL i=0;fac[i]<=n;i++){            ans=ans*(p[n][fac[i]]-p[n-k][fac[i]]-p[k][fac[i]]+1);        }        printf("%lld\n",ans);    }
节省63Ms。嘿嘿

hdu 2879 hehe
http://acm.hdu.edu.cn/showproblem.php?pid=2879
In the equation X^2≡X(mod N) where x∈[0,N-1], we define He[N] as the number of solutions.
And furthermore, define HeHe[N]=He[1]*……*He[N]
Now here is the problem, write a program, output HeHe[N] modulo M for a given pair N, M.

分析:(注:本题自己纯属乱搞,没有严格证明)
时, x(x-1)%N=0, 此时的结果是x=1或者x=0.
he[N]=2当N=pq时(p和q是互质的),x(x-1)%N=0, 此时(1) x=kp (2) x=kq 再加上x=1,x=0, 所以he[N]=he[p]he[q],  那么这是一个积性函数。
时,  
那么hehe[N]就是:



#include <iostream>#include <cstdio>using namespace std;typedef long long LL;const int N=1e7+10;int pri[N],cnt;bool vis[N];void getpri(){    for(int i=2;i<N;i++){        if(!vis[i]) pri[cnt++]=i;        for(int j=0;j<cnt&&i*pri[j]<N;j++){            vis[i*pri[j]]=1;            if(i%pri[j]==0) break;        }    }}LL power(LL a,LL p,LL m){    LL ans=1;    while(p){        if(p&1) ans=ans*a%m;        a=a*a%m;        p>>=1;    }    return ans;}int main(){    LL n,m;    getpri();    int t;    cin>>t;    while(t--){        scanf("%lld%lld",&n,&m);        LL p=0;        for(int i=0;i<cnt&&pri[i]<=n;i++){            p+=n/pri[i];        }        printf("%lld\n",power(2,p,m));    }    return 0;}



0 0
原创粉丝点击