杜教筛--[CQOI2015]选数

杜教筛这东西其实思想和莫比乌斯反演十分类似,通过解出比较好求的函数快速推得要求但比较难求的函数。

首先它所用的知识是一个叫狄利克雷卷积的东西,对于两个积性函数f(n),g(n)f(n),g(n),定义它们的狄利克雷卷积为:(f∗g)(n)=∑d|n f(d)∗g(n/d),(就是莫比乌斯反演中原本“1”的位置被改为函数),这样我们可以用(f∗g)和g这两个函数推出我们所要的函数f。

以下转载自:https://www.cnblogs.com/Mychael/p/8744633.html

而g在求莫比乌斯反演时是恒为一的函数,(f∗g)因为miu函数和“1”函数互为逆元可推得相乘为单位元,即[n==1],那么这玩意可以先预处理掉一部分答案(线性筛筛个2/3次左右),然后整除分块加记忆化搜索。

例题:[CQOI2015]选数

链接:https://www.luogu.org/problemnew/show/P3172

其实这道题不算杜教筛例题,因为它的标算是利用好h-l1e5,但sw大佬随便就用杜教筛艹过去了,蒟蒻自然要跟大佬看齐了。。这道题用杜教筛的原因是推出的式子里莫比乌斯函数最大可能有1e9,套上杜教筛跑整除分块的莫比乌斯反演就可以过了(复杂度最差是sqrt(1e5)*O(1e9*2/3=1e6)的样子?但实际上远远不到,记忆化搜索杜教筛均摊下来每次应该不会都有O(2/3),反正能过就行了。。

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
const int N=1e6;
bool vis[N+10];int miu[N+10],prime[N+10],pnum,sum[N+10];
map<int,int>vi;
int qpow(int x,int y)
{
    int res=1;
    while(y)
    {
        if(y&1)res=1LL*res*x%mod;
        x=1LL*x*x%mod,y>>=1;
    }
    return res;
}
int ask(int x)
{
    if(x<=N)return sum[x];
    int tp=vi[x];
    if(tp)return tp;
    tp=1;
    for(int l=2,r;l<=x;l=r+1)
    {
        r=x/(x/l);
        tp-=ask(x/l)*(r-l+1);
    }
    return vi[x]=tp;
}
void init()
{
    miu[1]=1;
    for(int i=2;i<=N;i++)
    {
        if(!vis[i])miu[i]=-1,prime[++pnum]=i;
        for(int j=1;j<=pnum&&prime[j]*i<=N;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)break;
            miu[i*prime[j]]=-miu[i];
        }
    }
    for(int i=1;i<=N;i++)
        sum[i]=sum[i-1]+miu[i];
}
int main()
{
    int n,k,L,H,ans=0;
    init();
    cin>>n>>k>>L>>H;
    L--,H/=k,L/=k;
    for(int l=1,r;l<=H;l=r+1)
    {
        r=H/(H/l);
        if(L>=l)r=min(r,L/(L/l));
        ans=(1LL*qpow(H/l-L/l,n)*(ask(r)-ask(l-1))%mod+ans)%mod;
    }
    printf("%d\n",(ans+mod)%mod);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值