• luoguP3172 [CQOI2015]选数


    题意

    所求即为:
    (sumlimits_{i_1=L}^{R}sumlimits_{i_2=L}^{R}...sumlimits_{i_k=L}^{R}[gcd(i_1,i_2,...,i_k)=k])
    套路地进行莫比乌斯反演:
    (sumlimits_{i_1=frac{L-1}{k}+1}^{frac{R}{k}}sumlimits_{i_2=frac{L-1}{k}+1}^{frac{R}{k}}...sumlimits_{i_k=frac{L-1}{k}+1}^{frac{R}{k}}[gcd(i_1,i_2,...,i_k)=1])
    (sumlimits_{i_1=frac{L-1}{k}+1}^{frac{R}{k}}sumlimits_{i_2=frac{L-1}{k}+1}^{frac{R}{k}}...sumlimits_{i_k=frac{L-1}{k}+1}^{frac{R}{k}}sumlimits_{x|gcd(i_1,i_2,...,i_k)}mu(x))
    (sumlimits_{x=1}^{frac{R}{k}}mu(x)sumlimits_{i_1=frac{L-1}{k}+1}^{frac{R}{k}}sumlimits_{i_2=frac{L-1}{k}+1}^{frac{R}{k}}...sumlimits_{i_k=frac{L-1}{k}+1}^{frac{R}{k}}[x|gcd(i_1,i_2,...,i_k)])
    (sumlimits_{x=1}^{frac{R}{k}}mu(x)sumlimits_{i_1=frac{L-1}{k*x}+1}^{frac{R}{k*x}}sumlimits_{i_2=frac{L-1}{k*x}+1}^{frac{R}{k*x}}...sumlimits_{i_k=frac{L-1}{k*x}+1}^{frac{R}{k*x}}1)
    (sumlimits_{x=1}^{frac{R}{k}}mu(x)(frac{R}{k*x}-frac{L-1}{k*x})^n)

    杜教筛求(sumlimits_{x=1}^{frac{R}{k}}mu(x))就可以除法分块了

    code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    const int inf=1e9;
    const ll mod=1000000007;
    int n,K,L,R;
    int mu[maxn],sum[maxn];
    ll ans;
    bool vis[maxn];
    vector<int>prime;
    unordered_map<int,int>mp;
    inline ll power(ll x,ll k,ll mod)
    {
    	ll res=1;
    	while(k)
    	{
    		if(k&1)res=res*x%mod;
    		x=x*x%mod;k>>=1;
    	}
    	return res;
    }
    inline void pre_work(int n)
    {
    	vis[1]=1;mu[1]=1;
    	for(int i=2;i<=n;i++)
    	{
    		if(!vis[i])prime.push_back(i),mu[i]=-1;
    		for(unsigned int j=0;j<prime.size()&&i*prime[j]<=n;j++)
    		{
    			vis[i*prime[j]]=1;
    			if(i%prime[j]==0)break;
    			mu[i*prime[j]]=-mu[i];
    		}
    	}
    	for(int i=1;i<=n;i++)sum[i]=sum[i-1]+mu[i];
    }
    inline int getsum(int x)
    {
    	if(x<=100000)return sum[x];
    	if(mp.count(x))return mp[x];
    	ll res=1;
    	for(int l=2,r;l<=x;l=r+1)
    	{
    		r=x/(x/l);
    		res=(res-(r-l+1)*getsum(x/l)%mod)%mod;
    	}
    	return mp[x]=(res%mod+mod)%mod;
    }
    int main()
    {
    	pre_work(100000);
    	scanf("%d%d%d%d",&n,&K,&L,&R);
    	L=(L-1)/K,R=R/K;
    	for(int l=1,r;l<=R;l=r+1)
    	{
    		r=min(L/l?L/(L/l):inf,R/(R/l));
    		ans=((ans+1ll*(getsum(r)-getsum(l-1))*power(R/l-L/l,n,mod)%mod)%mod+mod)%mod;
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    nginx原理及常用配置
    课程作业03-1
    Java动手动脑02
    Java课程作业02
    java课堂测试2
    Java验证码程序
    课程作业02-2
    课程作业02-1
    课程作业01
    《大道至简》第一章伪代码
  • 原文地址:https://www.cnblogs.com/nofind/p/11954084.html
Copyright © 2020-2023  润新知