积性函数,线性筛入门 HDU - 2879

Posted lmcc1108

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了积性函数,线性筛入门 HDU - 2879相关的知识,希望对你有一定的参考价值。

HDU - 2879 HeHe

  题意:He[N]为[0,N1]范围内有多少个数满足式子x2x (mod N),HeHe[N]=He[1]××He[N]

  我是通过打表发现的he[x]=2k,k为x是质因子个数,不过这是可以通过积性函数证明的。

  关于积性函数的定义:

对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时,f(ab)=f(a)f(b),在数论上就称它为积性函数。若对于某积性函数 f(n) ,就算a, b不互质,也有f(ab)=f(a)f(b),则称它为完全积性的。

  引用证明,HDU 2879 HeHe (素数+积性函数及证明)

  知道了,he[x]=2k之后,接下来求hehe[n]其实就是求2k1+k2+...kn,具体实现上,有好几种方法。

  普通的埃氏筛,对于每个数它的每个质因子就在指数贡献一个了1,所以我们可以先把质数筛出来,然后再看n范围内包含有多少个这个质数的倍数。

技术图片
 1 #include<cstdio>
 2 typedef long long ll;
 3 const int N=10000007;
 4 bool nop[N]=false;
 5 int pn,pri[N/10];
 6 void init()
 7 
 8     pn=0;
 9     for(int i=2;i<N;i++)
10     
11         if(!nop[i])
12         
13             pri[pn++]=i;
14             for(int j=i<<1;j<N;j+=i)
15                 nop[j]=true;
16         
17     
18 
19 ll pow(int b,int mod)
20 
21     ll ans=1,a=2ll;
22     while(b)
23     
24         if(b&1)
25             ans=(ans*a)%mod;
26         a=(a*a)%mod;
27         b>>=1;
28     
29     return ans%mod;
30 
31 int main()
32 
33     init();
34     int t,n,m;
35     scanf("%d",&t);
36     while(t--)
37     
38         scanf("%d%d",&n,&m);
39         int sum=0;
40         for(int i=0;i<pn&&pri[i]<=n;i++)
41             sum+=n/pri[i];
42         printf("%lld\\n",pow(sum,m));
43     
44     return 0;
45 
埃氏筛

  第二个线性筛(欧拉筛),为什么欧拉筛是O(n),,可以看这个证明线性筛(欧拉筛)然后,前面有证明he是积性函数,所有我们就可以通过欧拉筛先把he预处理处理。

技术图片
#include<cstdio>
typedef long long ll;
const int N=10000007;
bool nop[N]=false;
int pn,pri[N/10],he[N];
void init()

    pn=0;
    for(int i=2;i<N;i++)
    
        if(!nop[i])
        
            he[i]=1;//he[i]=2^1, 
            pri[pn++]=i;
        
        for(int j=0;j<pn&&1ll*i*pri[j]<N;j++)
        
            int temp=i*pri[j];
            nop[temp]=true;
            if(i%pri[j]==0)
            
                he[temp]=he[i];//temp的质因子数跟i相同 
                break;
            
            he[temp]=he[i]+he[pri[j]];//f[a*b]=f[a]*fa[b],
            //这里he保存的是指数,所以是+ 
        
    

ll pow(int b,int mod)

    ll ans=1,a=2ll;
    while(b)
    
        if(b&1)
            ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    
    return ans%mod;

int main()

    init();
    int t,n,m;
    scanf("%d",&t);
    while(t--)
    
        scanf("%d%d",&n,&m);
        int sum=0;
        for(int i=1;i<=n;i++)
            sum+=he[i];
        printf("%lld\\n",pow(sum,m));
    
    return 0;
欧拉筛

 

以上是关于积性函数,线性筛入门 HDU - 2879的主要内容,如果未能解决你的问题,请参考以下文章

线性筛

线性筛与积性函数

线性筛及其扩展-积性函数

模版线性筛(素数,欧拉函数,莫比乌斯函数)

欧拉筛法(线性筛法)与解积性函数

线性筛-euler,强大O(n)