zoukankan      html  css  js  c++  java
  • LOJ#2095 选数

    给定n,k,l,r

    问从[l, r]中选出n个数gcd为k的方案数。

    解:稍微一想就能想到反演,F(x)就是[l, r]中x的倍数个数的n次方。

    后面那个莫比乌斯函数随便怎么搞都行,当然因为这是杜教筛的题就杜教筛了。

    然后写一写,交上去80分......

    然后枚举一下d是k的多少倍,我们发现F(x)的计算式[(r / x) - ((l - 1) / x)]n可以整除分块...

    然后就做完了。

     1 #include <cstdio>
     2 #include <map>
     3 #include <algorithm>
     4 
     5 typedef long long LL;
     6 const int N = 1000010, T = 1000008;
     7 const LL MO = 1000000007;
     8 
     9 std::map<LL, LL> mp;
    10 int p[N], top, miu[N];
    11 LL n, k, l, r, Miu[N], L, R;
    12 bool vis[N];
    13 
    14 inline void getp(int n) {
    15     miu[1] = 1;
    16     for(int i = 2; i <= n; i++) {
    17         if(!vis[i]) {
    18             p[++top] = i;
    19             miu[i] = -1;
    20         }
    21         for(int j = 1; j <= top && i * p[j] <= n; j++) {
    22             vis[i * p[j]] = 1;
    23             if(i % p[j] == 0) {
    24                 break;
    25             }
    26             miu[i * p[j]] = -miu[i];
    27         }
    28     }
    29     for(int i = 1; i <= n; i++) {
    30         Miu[i] = Miu[i - 1] + miu[i];
    31     }
    32     return;
    33 }
    34 
    35 inline LL qpow(LL a, LL b) {
    36     LL ans = 1;
    37     a %= MO;
    38     while(b) {
    39         if(b & 1) ans = ans * a % MO;
    40         a = a * a % MO;
    41         b = b >> 1;
    42     }
    43     return ans;
    44 }
    45 
    46 LL getMiu(LL x) {
    47     if(x <= 0) return 0;
    48     if(x <= T) return Miu[x];
    49     if(mp.count(x)) return mp[x];
    50     LL ans = 1;
    51     for(LL i = 2, j; i <= x; i = j + 1) {
    52         j = x / (x / i);
    53         ans -= (j - i + 1) % MO * getMiu(x / i) % MO;
    54         ans %= MO;
    55     }
    56     return mp[x] = (ans + MO) % MO;
    57 }
    58 
    59 LL F(LL x) {
    60     LL temp = (R / x) - (L / x);
    61     return qpow(temp, n);
    62 }
    63 
    64 int main() {
    65     getp(T);
    66     scanf("%lld%lld%lld%lld", &n, &k, &l, &r);
    67     LL ans = 0;
    68     L = (l - 1) / k, R = r / k;
    69     for(LL i = 1, j; i <= R; i = j + 1) {
    70         if(L / i) j = std::min(R / (R / i), L / (L / i));
    71         else if(R / i) j = R / (R / i);
    72         else j = R;
    73         ans += F(i) * (getMiu(j) - getMiu(i - 1)) % MO;
    74         ans %= MO;
    75     }
    76     printf("%lld
    ", (ans + MO) % MO);
    77 
    78     return 0;
    79 }
    AC代码

    整除分块的时候要判断是不是0啊......

  • 相关阅读:
    拖拽 上传文件
    复制文本消息
    zTree 显示为‘aa’,当选择aa时,传的参数为‘22’
    移动端 动画 启动硬件加速
    jquery 停止动画与切换
    CSS小技巧-怎样让每行多余的文字显示文省略号?
    CSS小技巧-两个盒子之间的间距问题
    CSS小技巧-为内盒子添加margin-top时,会带着父盒子一起下来,如何解决?
    小K的H5之旅-CSS基础(一)
    小K的H5之旅-HTML的基本结构与基本标签
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10444324.html
Copyright © 2011-2022 走看看