zoukankan      html  css  js  c++  java
  • 【bzoj3930】选数 容斥原理+暴力

    Description

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

    Input

    输入一行,包含4个空格分开的正整数,依次为N,K,L和H。

    Output

    输出一个整数,为所求方案数。

    Sample Input

    2 2 2 4

    Sample Output

    3

    HINT

    样例解释

    所有可能的选择方案:(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4)

    其中最大公约数等于2的只有3组:(2, 2), (2, 4), (4, 2)

    对于100%的数据,1≤N,K≤109,1≤L≤H≤109,H-L≤10^5

    Sol

    首先最重要的条件:(H-L)(10^5)以内,这说明区间内(gcd(i,j)<10^5),那么我们可以直接枚举gcd是多少,然后进行计算。

    具体地,我们把H和L都/=K,这样所求变成了(gcd(a_1,a_2,...,a_n)=1)的方案数。

    我们设(f[i])表示区间内(gcd)为i的方案数,那么(f[i])可以再次通过除以(i)然后直接求区间长度的方式解决,但是这样我们会把(sum_{i|d}f[d])也算上,所以需要把i倍数的d减掉,倒推即可。

    本题的三个小细节:

    1. 如果K在L和R的范围内,那么ans++。
    2. 如果(L\%K)不等于0,那么新的L等于(L/K+1),因为原来的L往后一小部分是不合法的,要去掉,内层统计时亦是如此。
    3. 要减去N个数都相同的方案,因为显然这种方案不成立,具体地,快速幂后面减个len就行。

    时间复杂度(O(nlogn))

    Code

    #include <cstdio>
    int N,K,L,R,l,r,M,m,F,f[100005],P=1e9+7;
    int ksm(int a,int b){int res=1;for(;b;b>>=1,a=1ll*a*a%P) if(b&1) res=1ll*res*a%P;return res;}
    int main()
    {
        scanf("%d%d%d%d",&N,&K,&L,&R);
        if(L<=K&&K<=R) F++;
        L=L%K?L/K+1:L/K,R/=K,M=R-L+1;
        for(int i=M;i;i--)
        {
            l=L%i?L/i+1:L/i,r=R/i,m=r-l+1;
            if(l<r){f[i]=(ksm(m,N)-m+P)%P;for(int j=(i<<1);j<=M;j+=i) f[i]=(f[i]-f[j]+P)%P;}
        }
        printf("%d
    ",(F+f[1])%P);
    }
    
  • 相关阅读:
    python之socket编程
    python之异常处理
    面向对象进阶
    openstack的网络配置
    VLAN,GRE,VXLAN
    三节点搭建openstack-Mitaka版本
    矩阵转换
    判断区域相交的方法
    Centos 6.5 Multipath 初始配置
    CentOS开机自动运行程序的脚本
  • 原文地址:https://www.cnblogs.com/CK6100LGEV2/p/9401574.html
Copyright © 2011-2022 走看看