首页 > 代码库 > BZOJ 3930 选数
BZOJ 3930 选数
莫比乌斯反演+杜教筛。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<map>#define maxn 10000000#define mod 1000000007#define inf 0x7f7f7f7f7f7f7f7fLLusing 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\n",(ans+mod)%mod); return 0;}
BZOJ 3930 选数
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。