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

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3930


    求从${l~r}$中选$n$个数,最大公约数为$k$的方案数。


    $gcd$?一开始就往莫比乌斯反演上面想,考虑一下如选两个数是什么样子的。

    ${sum _{i=L}^{R}sum _{j=L}^{R}left [ gcd(i,j)=k ight ]}$

    ${=sum _{i=left lfloor frac{L}{K} ight floor}^{left lfloor frac{R}{K} ight floor}sum _{j=left lfloor frac{L}{K} ight floor}^{left lfloor frac{R}{K} ight floor}left [ gcd(i,j)=1 ight ]}$

    ${=sum _{i=left lfloor frac{L}{K} ight floor}^{left lfloor frac{R}{K} ight floor}sum _{j=left lfloor frac{L}{K} ight floor}^{left lfloor frac{R}{K} ight floor}sum _{d|gcd(i,j)}mu(d)}$

    ${=sum_{d=1}^{left lfloor frac{R}{K} ight floor}mu (d)(left lfloor frac{R}{Kd} ight floor-left lfloor frac{L-1}{Kd} ight floor)^{2}}$

    同理的,如果是选$n$个数:

    $${sum_{d=1}^{left lfloor frac{R}{K} ight floor}mu (d)(left lfloor frac{R}{Kd} ight floor-left lfloor frac{L-1}{Kd} ight floor)^{n}}$$

    接下来线性筛,分块直接算即可。


    但是

      MDZZ,${R-L<=1e5}$的这个条件没用到,嗯这个范围应该是个${log^{1e5}}$。

      令$f[i]$表示$gcd=i$的方案数,${Aleft lceil frac{L}{K} ight ceil}$,${B=left lfloor frac{R}{K} ight floor}$。

      转移为:$${f[i]=(r-l+1)^{n}-t-sum _{i|j}f[j]}$$

      枚举$i$,$j$,其中$j$是调和级数的意义,复杂度${O(nlog(R-L))}$


     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<cstring>
     8 using namespace std;
     9 #define maxn 1001000
    10 #define llg long long 
    11 #define mod 1000000007
    12 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    13 llg n,m,f[maxn],L,R,k;
    14 
    15 llg ksm(llg x,llg y)
    16 {
    17     llg ans=1;
    18     while (y)
    19     {
    20         if (y&1) ans=ans*x%mod;
    21         x=x*x%mod;
    22         y>>=1;
    23     }
    24     return ans;
    25 }
    26 
    27 int main()
    28 {
    29     yyj("bzoj3930");
    30     cin>>n>>k>>L>>R;
    31     for (llg i=R-L;i>=1;i--)
    32     {
    33         llg l=(L-1)/(k*i),r=R/(k*i);
    34         f[i]=(ksm(r-l,n)-(r-l)+mod) %mod;
    35         for (llg j=2;i*j<=R-L;j++)
    36         {
    37             f[i]=f[i]-f[i*j]+mod;
    38             f[i]%=mod;
    39         }
    40     } 
    41     if (L<=k && k<=R) f[1]++;
    42     cout<<f[1];
    43     return 0;
    44 }
    本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    移植ssh到mini2440
    VMware中Ubuntu安装VMware Tools步骤及问题解决方法
    Linux的网卡由eth0变成了eth1,如何修复
    mini2440移植所有驱动到3.4.2内核详细解说
    单片机的一生(感觉在说大部分人)
    mini2440移植linux-3.4.2内核详细解说
    Ubuntu中恢复桌面的上下默认面板命令
    mini2440移植最新u-boot-2012.04.01详细解说
    MyEclipse CI 2018.8.0 官方最新免费版(破解文件+激活工具+破解教程)
    cocos 获取一个骨骼动画多次显示播放
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6391829.html
Copyright © 2011-2022 走看看