bzoj3930: [CQOI2015]选数

我真是中考跑傻了首先第一步就是区间同除K变成求gcd==1都忘了然后就是倒着枚举倍数i求当前区间内i的倍数的个数用f[i]表示很容易发现这是一个容斥原理比较小i要减去前面全部的倍数

需要判一下边界,这个东西我WA了3次。。。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL mod=1000000007;
LL MOD(LL x){return (x%mod+mod)%mod;}

//返回区间内i的倍数的个数 
LL L,H;
LL getnum(LL i){return H/i-(L-1)/i;}

LL f[110000];
LL quick_pow(LL A,LL p)
{
    LL ans=1;
    while(p>0)
    {
        if(p%2==1)ans=MOD(ans*A);
        A=MOD(A*A);p/=2;
    }
    return ans;
}
int main()
{
    LL N,K;
    scanf("%lld%lld%lld%lld",&N,&K,&L,&H);
    L=(L%K==0)?L/K:L/K+1;
    H/=K;
    for(LL i=H-L+1;i>=1;i--)
    {
        LL num=getnum(i);
        if(num>0)
        {
            f[i]=MOD(quick_pow(num,N)-num);
            for(LL j=i*2;j<=H-L+1;j+=i)f[i]=MOD(f[i]-f[j]);
        }
    }
    if(L==1)f[1]=MOD(f[1]+1);
    printf("%lld\n",f[1]);
    return 0;
}

 

posted @ 2018-04-20 15:33  AKCqhzdy  阅读(105)  评论(0编辑  收藏  举报