zoukankan      html  css  js  c++  java
  • bzoj4407: 于神之怒加强版

    懵逼乌斯反演裸题

    画完柿子只要预处理S(i)=sigema(d|i)d u(i/d)*d^k

    线性筛它一手

    i%prime[j]!=0的话,首先i的因子也是i*prime[j]的因子,但是由于多了一个质因子所以正负性反过来。其次多了这个prime[j],i的所有因子都可以乘这个数,同样是它的因子,值的变化就是prime[j]^k。合起来S[i*prime[j]]=-S[i]+S[i]*prime[j]^k,结果亮老师一眼秒了S这个东西是一个积性函数,我一脸懵逼。。。想一想当是质数的时候,好像S值就是prime^k-1。。。然后百度一手发现这个是狄利克雷卷积的形式。。。好的扔了

    i%prime[j]==0,我们换种表示方法,设i=x*p^q,对于S[i],有贡献的d,只能具有q或q-1个p,而对于i*prime[j]也就是x*p^(q+1)来说,有贡献的d是具有q+1或q个p的。而贡献,是d^k。那么前面的q对应后面的q+1,前面的q-1对应后面的q,要乘上的就是prime[j]^k

    没取模好还挂了一次。。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const int mod=1e9+7;
    
    int K;
    int quick_pow(int A)
    {
        int ret=1;int p=K;
        while(p!=0)
        {
            if(p%2==1)ret=(LL)ret*A%mod;
            A=(LL)A*A%mod;p/=2;
        }
        return ret;
    }
    int pr,prime[5000010],u[5000010],mi[5000010],S[5000010];
    bool v[5000010];
    void get_prime()
    {
        pr=0;u[1]=1;mi[1]=1;S[1]=1;
        for(int i=2;i<=5000000;i++)
        {
            mi[i]=quick_pow(i);
            if(v[i]==false)
            {
                u[i]=-1,S[i]=(mi[i]-1+mod)%mod;
                prime[++pr]=i;
            }
            for(int j=1;j<=pr&&i*prime[j]<=5000000;j++)
            {
                v[i*prime[j]]=true;
                if(i%prime[j]==0)
                {
                    u[i*prime[j]]=0,S[i*prime[j]]=(LL)S[i]*mi[prime[j]]%mod;
                    break;
                }
                else u[i*prime[j]]=-u[i],S[i*prime[j]]=(LL)S[i]*S[prime[j]]%mod;
            }
        }
        for(int i=2;i<=5000000;i++)S[i]=(S[i]+S[i-1])%mod;
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int T;
        scanf("%d%d",&T,&K);get_prime();
        while(T--)
        {
            int n,m,last,ans=0;
            scanf("%d%d",&n,&m);
            if(n>m)swap(n,m);
            for(int i=1;i<=n;i=last+1)
            {
                last=min(n/(n/i),m/(m/i));
                ans=((LL)ans+(LL)(m/i)*(LL)(n/i)%mod*(LL)(S[last]-S[i-1]+mod)%mod)%mod;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    LaTeX技巧22:LaTeX文档中的参考文献初级
    latex 三个不同的图放在一行且每个图都有注释
    CTeX学习心得总结
    latex不能识别eps图片
    山东大学《运筹学》课程课件
    高级算法设计讲义 Lecture Notes for Advanced Algorithm Design
    《计算复杂性》课件
    全球知名大学课件下载地址汇总
    用LaTeX写线性规划
    有感北大校长王恩哥的十句话
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9870049.html
Copyright © 2011-2022 走看看