zoukankan      html  css  js  c++  java
  • [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;
    }
  • 相关阅读:
    51 Nod 1068 Bash游戏v3
    51 Nod Bash 游戏v2
    51 Nod 1073 约瑟夫环
    UVA 12063 Zeros and ones 一道需要好好体会的好题
    51 Nod 1161 Partial sums
    2018中国大学生程序设计竞赛
    UVA 11971 Polygon
    UVA 10900 So do you want to be a 2^n-aire?
    UVA 11346 Possibility
    python with as 的用法
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/10437903.html
Copyright © 2011-2022 走看看