zoukankan      html  css  js  c++  java
  • 积性函数,线性筛入门 HDU

    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
    ",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
    ",pow(sum,m));
        }
        return 0;
    }
    欧拉筛
  • 相关阅读:
    Steady Cow Assignment POJ
    二分图多重匹配问题
    Tour HDU
    奔小康赚大钱 HDU
    Strategic Game HDU
    Antenna Placement POJ
    Oil Skimming HDU
    Rain on your Parade HDU
    假如,
    这样也可以,insert,,
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/11089153.html
Copyright © 2011-2022 走看看