• [CQOI2015]选数


    题目描述

    我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案。小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一步研究。然而他很快发现工作量太大了,于是向你寻求帮助。你的任务很简单,小z会告诉你一个整数K,你需要回答他最大公约数刚好为K的选取方案有多少个。由于方案数较大,你只需要输出其除以1000000007的余数即可。

    题解

    首先转化一下,变成求[L/k,R/k]的答案,此时公约数就变成了1。

    但这样我们还是不能直接枚举GCD,它的范围是1e9的。

    考虑区间长度最大为1e5,说明其中任意两个不同的数的GCD是要小于区间长度的。

    所以我们设f[i]表示从区间中选n不完全相同的数GCDi的方案数。

    按照套路容斥一下。

    代码

    #include<iostream>
    #include<cstdio>
    #define N 100002
    using namespace std;
    typedef long long ll;
    const int mod=1000000007;
    ll f[N],n,k,l,r;
    inline ll rd(){
        ll x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    }
    inline ll power(ll x,ll y){
        ll ans=1;
        while(y){
            if(y&1)ans=ans*x%mod;x=x*x%mod;y>>=1;
        }
        return ans;
    }
    int main(){
        n=rd();k=rd();l=rd();r=rd();
        r=r/k;l=(l-1)/k;
        for(int i=r-l;i>=1;--i){
            int x=(r/i-l/i+mod)%mod;
            f[i]=(power(x,n)-(x)+mod)%mod;
            for(int j=i*2;j<=r-l;j+=i)f[i]=(f[i]-f[j]+mod)%mod;
        }
        if(!l)f[1]=(f[1]+1)%mod;
        cout<<f[1];
        return 0;
    }
  • 相关阅读:
    Python
    Python
    Python
    Python
    python
    python
    Python
    pure css做的pc登陆界面
    MvcAdmin功能介绍
    pure css做的手机版博客园(我自己博客)
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/10437903.html
Copyright © 2020-2023  润新知