zoukankan      html  css  js  c++  java
  • [BZOJ3930][CQOI2015]选数

    BZOJ
    Luogu
    原题因为(H-Lle10^5)的限制,其实可以不用杜教筛。不过去掉这个限制本题还是可做的。以下题解忽视这个条件并使用了杜教筛。

    sol

    首先(L=lfloorfrac {L-1}{K} floor)(R=lfloorfrac RK floor),转化为在这个区间里选出n个数使它们的(gcd)等于1.这个显然可以反演得到

    [ans=sum_{i=1}^{R}mu(i)(lfloorfrac Hi floor-lfloorfrac Li floor)^n ]

    后面一坨分块,然后需要快速求出(mu(i))的前缀和。
    杜教筛即可。

    code

    #include<cstdio>
    #include<algorithm>
    #include<map>
    using namespace std;
    const int mod = 1000000007;
    const int N = 5000000;
    int gi()
    {
        int x=0,w=1;char ch=getchar();
        while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
        if (ch=='-') w=0,ch=getchar();
        while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
        return w?x:-x;
    }
    int fastpow(int a,int b)
    {
        int res=1;
        while (b) {if (b&1) res=1ll*res*a%mod;a=1ll*a*a%mod;b>>=1;}
        return res;
    }
    int n,k,L,R,maxN,pri[N+5],tot,zhi[N+5],mu[N+5];
    map<int,int>M;
    void Mobius()
    {
        zhi[1]=mu[1]=1;
        for (int i=2;i<=N;i++)
        {
            if (!zhi[i]) pri[++tot]=i,mu[i]=-1;
            for (int j=1;j<=tot&&i*pri[j]<=N;j++)
            {
                zhi[i*pri[j]]=1;
                if (i%pri[j]) mu[i*pri[j]]=-mu[i];
                else break;
            }
        }
        for (int i=1;i<=N;i++) mu[i]+=mu[i-1];
    }
    int Mu(int x)
    {
        if (x<=maxN) return mu[x];
        if (M[x]) return M[x];
        int i=2,j,res=0;
        while (i<=x)
        {
            j=x/(x/i);
            res=(res+1ll*(j-i+1)*Mu(x/i)%mod)%mod;
            i=j+1;
        }
        return M[x]=(1-res+mod)%mod;
    }
    int main()
    {
        n=gi();k=gi();L=(gi()-1)/k;R=gi()/k;
        maxN=min(N,R);
        Mobius();
        int i=1,j,ans=0;
        while (i<=R)
        {
            j=R/(R/i);if (L/i) j=min(j,L/(L/i));
            ans=(ans+1ll*(Mu(j)-Mu(i-1)+mod)%mod*fastpow(R/i-L/i,n)%mod)%mod;
            i=j+1;
        }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    [LeetCode] Baseball Game
    [Linux] Shell Scripts
    [Linux] 正则表达式与文件格式化处理
    [Linux] 学习bash
    [Linux] vim程序编辑器
    [Linux] 文件与文件系统的压缩打包与备份
    [LeetCode] Reverse Words in a String
    [LeetCode] Reverse Integer
    [国嵌笔记][017][Makefile工程管理]
    [国嵌笔记][016][交叉工具链]
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8305196.html
Copyright © 2011-2022 走看看