zoukankan      html  css  js  c++  java
  • 【递推】BZOJ 3930: [CQOI2015]选数


     

    Description

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

    Input

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

    Output

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


      这道题有两种做法- -

      1.递推

      我们先设在一段区间[l,r]间选择n个元素,且它们的gcd为k*i的选择方案是f[i]。

      显然,[l,r]内能被k*i整除的数有(R-L+1)^n个(R=r/(i*k),L=l/(i*k))。但是,有一些选择是这种(L,L,L,L,L,L,...L),一共有(R-L+1)种,同时还有最大公约数是k*i的倍数的,我们也要减去。

      得到f[i]=(R-L+1)^n-(R-L+1)-f[k*i*a](a>=2 && k*i*a<=L-R+1)。

      输出f[1]即可。

      但是还有特殊情况。就是k在[l,r]间,所以这时f[1]++即可。

      2.mobius反演

      公式还是蛮容易的。。

      mobius公式推导:http://lzy-foenix.gitcafe.io/2015/04/09/BZOJ-3930-CQOI2015-%E9%80%89%E6%95%B0/

      关于阀值与μ的推导:http://www.cnblogs.com/Asm-Definer/p/4434601.html

      PoPoQQQ的两者结合:http://blog.csdn.net/popoqqq/article/details/44917831(画质感人- -)

      My Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 
     6 #define mod 1000000007
     7 
     8 #define maxn 100000
     9 
    10 using namespace std;
    11 
    12 long long f[maxn+1];
    13 
    14 long long qvod(long long x,long long k)
    15 {
    16     long long ans=1;
    17     while(k!=0)
    18     {
    19         if(k&1)ans=ans*x%mod;
    20         x=x*x%mod;
    21         k>>=1;
    22     }
    23     return ans;
    24 }
    25 
    26 int main()
    27 {
    28     int a,b,k,n;
    29     scanf("%d%d%d%d",&n,&k,&a,&b);
    30     int l=a/k,r=b/k;
    31     if(a%k)l++;
    32     for(int i=maxn;i>=1;i--)
    33     {
    34         int L=l/i,R=r/i;
    35         if(l%i)L++;
    36         if(l<=r)
    37         {
    38             f[i]=qvod(R-L+1,n);
    39             f[i]=(f[i]-(R-L+1)+mod)%mod;
    40             for(int j=i*2;j<=maxn;j+=i)f[i]=(f[i]-f[j]+mod)%mod;
    41         }
    42     }
    43     if(l==1)f[1]++;
    44     printf("%lld",(f[1]+mod)%mod);
    45     return 0;
    46 }
    View Code

      忽视奇怪的快速幂

  • 相关阅读:
    makefile vpath变量
    博客园 文章和随笔区别
    Linux OpenGL 实践篇-6 光照
    HTC Vive 叠影器无法创建设备
    Mybatis注解
    MyBatis缓存
    MyBatis关联映射
    动态sql
    MyBatis智能标签
    Mybatis模糊查询及自动映射
  • 原文地址:https://www.cnblogs.com/tuigou/p/4620242.html
Copyright © 2011-2022 走看看