积性函数

本文介绍了积性函数的概念,包括完全积性函数,并给出了欧拉函数和莫比乌斯函数作为例子。讨论了如何利用积性函数解决计算问题,如POJ 2992 Divisors和hdu 2879 hehe。提供了源代码来计算特定情况下积性函数的值,以及优化算法以提高计算效率。
积性函数:对于正整数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
大意:求解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: RE
LL 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
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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值