• [CQOI 2015]选数


    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≤10^9,1≤L≤H≤10^9,H-L≤10^5

    题解

    设 $F(x)$ 为 $xmid gcd$ 的个数, $f(x)$ 为 $gcd=x$ 的个数。

    egin{aligned}F(x)&=sum_{xmid d}f(d)\Rightarrow f(x)&=sum_{xmid d}muleft(frac{d}{x} ight)F(d)end{aligned}

    对于输入 $(N,K,L,H)$ 我们记 $leftlceilfrac{L}{K} ight ceil$ 为 $l$ ,记 $leftlfloorfrac{H}{K} ight floor$ 为 $h$ 。

    提出 $K$ ,答案就是 $$f(1)=sum_{i=1}^{h}mu(i)F(i)$$

    显然 $F(i)=left(leftlfloorfrac{h}{i} ight floor-leftlfloorfrac{l-1}{i} ight floor ight)^N$

    由于 $h$ 很大,我们还是不能枚举这个 $i$ 。考虑到这样一个问题:当 $i$ 很大时 $leftlfloorfrac{h}{i} ight floor-leftlfloorfrac{l-1}{i} ight floor$ 会变成 $0$ 或 $1$ 。实际上只要 $i>h-l$ 数值就为 $0$ 或 $1$ 了。

    那么现在答案就变成了 egin{aligned}&sum_{i=1}^{h-l}mu(i)left(leftlfloorfrac{h}{i} ight floor-leftlfloorfrac{l-1}{i} ight floor ight)^N+sum_{i=h-l+1}^hmu(i)leftlfloorfrac{h}{i} ight floor-leftlfloorfrac{l-1}{i} ight floor\=&sum_{i=1}^{h-l}mu(i)left(leftlfloorfrac{h}{i} ight floor-leftlfloorfrac{l-1}{i} ight floor ight)^N+sum_{i=1}^hmu(i)leftlfloorfrac{h}{i} ight floor-leftlfloorfrac{l-1}{i} ight floor-sum_{i=1}^{h-l}mu(i)leftlfloorfrac{h}{i} ight floor-leftlfloorfrac{l-1}{i} ight floorend{aligned}

    我们观察到式子 $sumlimits_{i=1}^hmu(i)leftlfloorfrac{h}{i} ight floor-leftlfloorfrac{l-1}{i} ight floor$ 的含义就是 $lsim r$ 区间内有是否有值为 $1$ ,所以等价于 $[Lleq Kwedge Kleq H]$ 。

    所以 $$ans=sum_{i=1}^{h-l}mu(i)left(left(leftlfloorfrac{h}{i} ight floor-leftlfloorfrac{l-1}{i} ight floor ight)^N-left(leftlfloorfrac{h}{i} ight floor-leftlfloorfrac{l-1}{i} ight floor ight) ight)+[Lleq Kwedge Kleq H]$$

     1 //It is made by Awson on 2018.1.24
     2 #include <set>
     3 #include <map>
     4 #include <cmath>
     5 #include <ctime>
     6 #include <queue>
     7 #include <stack>
     8 #include <cstdio>
     9 #include <string>
    10 #include <vector>
    11 #include <cstdlib>
    12 #include <cstring>
    13 #include <iostream>
    14 #include <algorithm>
    15 #define LL long long
    16 #define Abs(a) ((a) < 0 ? (-(a)) : (a))
    17 #define Max(a, b) ((a) > (b) ? (a) : (b))
    18 #define Min(a, b) ((a) < (b) ? (a) : (b))
    19 #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
    20 #define writeln(x) (write(x), putchar('
    '))
    21 #define lowbit(x) ((x)&(-(x)))
    22 using namespace std;
    23 const int N = 1e5;
    24 const int MOD = 1000000007;
    25 void read(int &x) {
    26     char ch; bool flag = 0;
    27     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
    28     for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
    29     x *= 1-2*flag;
    30 }
    31 void write(LL x) {
    32     if (x > 9) write(x/10);
    33     putchar(x%10+48);
    34 }
    35 
    36 int n, k, l, h, mu[N+5];
    37 int isprime[N+5], prime[N+5], tot;
    38 
    39 void get_mu() {
    40     memset(isprime, 1, sizeof(isprime)); isprime[1] = 0, mu[1] = 1;
    41     for (int i = 2; i <= N; i++) {
    42     if (isprime[i]) prime[++tot] = i, mu[i] = -1;
    43     for (int j = 1; j <= tot && i*prime[j] <= N; j++) {
    44         isprime[i*prime[j]] = 0;
    45         if (i%prime[j]) mu[i*prime[j]] = -mu[i];
    46         else {mu[i*prime[j]] = 0; break; }
    47     }
    48     }
    49 }
    50 int quick_pow(int a, int b) {
    51     int ans = 1;
    52     while (b) {
    53     if (b&1) ans = (LL)ans*a%MOD;
    54     a = (LL)a*a%MOD, b >>= 1;
    55     }
    56     return ans;
    57 }
    58 void work() {
    59     get_mu(); read(n), read(k), read(l), read(h);
    60     int flag = (l <= k && k <= h), ans = 0;
    61     l = ceil(1.*l/k), h = (h/k);
    62     for (int i = 1; i <= h-l; i++) ans = (ans+(LL)mu[i]*quick_pow(h/i-(l-1)/i, n)%MOD)%MOD;
    63     for (int i = 1; i <= h-l; i++) ans = (ans-(LL)mu[i]*(h/i-(l-1)/i)%MOD)%MOD;
    64     writeln((ans+flag+MOD)%MOD);
    65 }
    66 int main() {
    67     work();
    68     return 0;
    69 }
  • 相关阅读:
    AptitudeSystem 2.0
    angularjs开发常见问题-2(angularjs内置过滤器)
    经常使用 Java API
    Spring Boot JPA 连接数据库
    机房收费系统个人重构版:软工文档中那些图
    Android
    Spring Boot 动态数据源(多数据源自己主动切换)
    java的nio包的SelectionKey,Selector,SelectableChannel三者的缠绵关系概述
    初探linux子系统集之timer子系统(三)
    mobiscroll 案例git
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/8340308.html
Copyright © 2020-2023  润新知