首页 > 代码库 > 6069 筛法

6069 筛法

求给出l,r,k,求累加和d[i^k](i=[l~r]),其中 d(i):i 的因子个数 ,l,r<=1e12,k<=1e7,r-l<=1e6
n=a1^p1*a2^p2..an^pn 则因子个数为 (p1+1)*(p2+1)*..(pn+1)
n^k的因子数为(p1+k+1)*..(pn+k+1)
n的素因子<=sqrt(n),先晒出sqrt(r)内的素因子,对[l,r]每个数分解出其素因子的幂即可(用一个素数去更新它倍数的幂.)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e6+20;
const int M=1e6;
const ll mod=998244353;
ll L,R,k,T,f[N],pw[N],vis[N],p[N],pn=0;
void init()
{
    for(int i=2;i<=M;i++)
    {
        if(!vis[i])
        {
            p[pn++]=i;
            for(int j=i+i;j<=M;j+=i)
                vis[j]=1;
        }
    }
}
int main()
{
    init();
    cin>>T;
    while(T--)
    {
        ll ans=0;
        scanf("%lld%lld%lld",&L,&R,&k);
        if(L==1)
            ans++,L++;
        for(ll i=L;i<=R;i++)
            f[i-L]=i,pw[i-L]=1;
        for(int i=0;i<pn&&p[i]*p[i]<=R;i++)
        {
            //p[i]μ?±?êy?aê? 
            ll st=L,cnt;
            if(L%p[i])
                st=(L/p[i]+1)*p[i];
            for(ll j=st;j<=R;j+=p[i])
            {
                cnt=0;
                while(f[j-L]%p[i]==0)
                    cnt++,f[j-L]/=p[i];    
                pw[j-L]=(pw[j-L]*(cnt*k+1))%mod;        
            }
        }
        for(ll i=L;i<=R;i++)
        {
        //    cout<<i<<‘ ‘<<pw[i-L]<<endl;
            if(f[i-L]==1)
                ans=(ans+pw[i-L])%mod;
            else//该数为素数
                ans=(ans+pw[i-L]*(k+1))%mod;
        }
        printf("%lld\n",ans);        
    }
    return 0;
}

 

6069 筛法