• BZOJ 3930 选数


    莫比乌斯反演+杜教筛。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #define maxn 10000000
    #define mod 1000000007
    #define inf 0x7f7f7f7f7f7f7f7fLL
    using namespace std;
    long long n,k,l,r,miu[maxn+50],prime[maxn+50],top=0,ans=0;
    bool vis[maxn+50];
    map <long long,long long> mp;
    void linear_shaker()
    {
        miu[1]=1;
        for (long long i=2;i<=maxn;i++)
        {
            if (!vis[i])
            {
                prime[++top]=i;
                miu[i]=-1;
            }
            for (long long j=1;j<=top && i*prime[j]<=maxn;j++)
            {
                vis[i*prime[j]]=true;
                if (i%prime[j]==0)
                {
                    miu[i*prime[j]]=0;
                    break;
                }
                else miu[i*prime[j]]=-miu[i];
            }
        }
        for (long long i=1;i<=maxn;i++)
            miu[i]+=miu[i-1];
    }
    long long f_pow(long long a,long long b)
    {
        long long base=a,ans=1;
        while (b)
        {
            if (b&1) ans=(ans*base)%mod;
            base=(base*base)%mod;
            b>>=1;
        }
        return ans;
    }
    long long ask(long long x)
    {
        if (x<=maxn) return miu[x];
        if (mp.find(x)!=mp.end()) return mp[x];
        long long pos=2,last=1,ret=0;
        while (pos<=x)
        {
            last=x/(x/pos);
            ret+=(last-pos+1)*ask(x/pos);
            pos=last+1;
        } 
        return mp[x]=1-ret;
    }
    int main()
    {
        scanf("%lld%lld%lld%lld",&n,&k,&l,&r);
        linear_shaker(); 
        long long pos=1,last=0;
        while (pos<=(r/k))
        {
            long long ret1=(r/k)/((r/k)/pos),ret2;
            if (!((l-1)/(k*pos))) ret2=inf;
            else ret2=((l-1)/k)/(((l-1)/k)/pos);
            last=min(ret1,ret2);
            ret1=(ask(last)-ask(pos-1));ret2=f_pow(r/(k*pos)-(l-1)/(k*pos),n);
            ans+=((ask(last)-ask(pos-1))*f_pow(r/(k*pos)-(l-1)/(k*pos),n))%mod;
            if (ans<mod) ans=(ans+mod)%mod;
            pos=last+1;
        }
        printf("%lld
    ",(ans+mod)%mod);
        return 0;
    }
  • 相关阅读:
    JS知识点简单总结
    Js答辩总结
    JS答辩习题
    轮播
    jQuery选择器总结
    JS的魅力
    JS与JAVA数据类型的区别
    单表查询、多表查询、虚拟表连接查询
    Mysql基本语句
    Mysql数据库
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5886086.html
Copyright © 2020-2023  润新知