bzoj4652 Noi2016 循环之美

题面bzoj4652

题意:对于 1 ≤ x ≤ n 1 \le x \le n 1xn 1 ≤ y ≤ m 1 \le y \le m 1ym,有多少个在 k k k进制下数值互不相等的纯循环小数 x y \frac x y yx 1 ≤ n , m ≤ 1 0 9 1 \le n, m \le 10^9 1n,m109 2 ≤ k ≤ 2000 2 \le k \le 2000 2k2000

题解:首先考虑10进制下的纯循环小数,一定可以表示成 a 1 0 k − 1 \frac a {10 ^k - 1} 10k1a的形式(不一定是最减分数)

猜想 k k k进制下可以表示成 a k b − 1 \frac a {k^b - 1} kb1a,所以 y ∣ ( k b − 1 ) y \mid (k^b - 1) y(kb1)

k b − 1 ≡ 0 ( m o d y ) → k b ≡ 1 ( m o d y ) k^b-1 \equiv 0 \pmod y \to k^b \equiv 1 \pmod y kb10(mody)kb1(mody)

所以 g c d ( k , y ) = 1 gcd (k, y) = 1 gcd(k,y)=1。又因为是最简分数(要求数值互不相等),所以 g c d ( x , y ) = 1 gcd (x, y) = 1 gcd(x,y)=1

这一段也可以用纯循环小数定义证明: x k b ≡ x ( m o d y ) xk^b \equiv x \pmod y xkbx(mody)


所以问题变成求: ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = 1 ] [ g c d ( j , k ) ] = 1 \sum _{i=1} ^n \sum _{j=1} ^m [gcd (i, j) = 1] [gcd (j, k)] = 1 i=1nj=1m[gcd(i,j)=1][gcd(j,k)]=1

∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = 1 ] [ g c d ( j , k ) = 1 ] = ∑ j = 1 m [ g c d ( j , k ) = 1 ] ∑ i = 1 n [ g c d ( i , j ) = 1 ] = ∑ j = 1 m [ g c d ( j , k ) = 1 ] ∑ i = 1 n ∑ d ∣ i , d ∣ j μ ( d ) = ∑ d = 1 n μ ( d ) ∑ d ∣ i n ∑ d ∣ j m [ g c d ( j , k ) = 1 ] = ∑ d = 1 n [ g c d ( d , k ) = 1 ] μ ( d ) ∑ i = 1 n d ∑ j = 1 m d [ g c d ( j , k ) = 1 ] = ∑ d = 1 n [ g c d ( d , k ) = 1 ] μ ( d ) ⌊ n d ⌋ ∑ j = 1 m d [ g c d ( j , k ) = 1 ] \begin {aligned} & \sum _{i=1} ^n \sum _{j=1} ^m [gcd (i, j) = 1] [gcd (j, k) = 1] \\ = & \sum _{j=1} ^m [gcd (j, k) = 1] \sum _{i=1} ^n [gcd (i, j) = 1] \\ = & \sum _{j=1} ^m [gcd (j, k) = 1] \sum _{i=1} ^n \sum _{d \mid i, d \mid j} \mu (d) \\ = & \sum _{d=1} ^n \mu (d) \sum _{d \mid i} ^n \sum _{d \mid j} ^m [gcd (j, k) = 1] \\ = & \sum _{d = 1} ^n [gcd (d, k) = 1] \mu (d) \sum _{i = 1} ^{\frac n d} \sum _{j=1} ^{\frac m d} [gcd (j, k) = 1] \\ = & \sum _{d = 1} ^n [gcd (d, k) = 1] \mu (d) \lfloor \frac n d \rfloor \sum _{j=1} ^{\frac m d} [gcd (j, k) = 1] \end {aligned} =====i=1nj=1m[gcd(i,j)=1][gcd(j,k)=1]j=1m[gcd(j,k)=1]i=1n[gcd(i,j)=1]j=1m[gcd(j,k)=1]i=1ndi,djμ(d)d=1nμ(d)dindjm[gcd(j,k)=1]d=1n[gcd(d,k)=1]μ(d)i=1dnj=1dm[gcd(j,k)=1]d=1n[gcd(d,k)=1]μ(d)dnj=1dm[gcd(j,k)=1]

相当于需要求两个前缀和:

f ( x ) = ∑ i = 1 x [ g c d ( i , k ) ] = 1 f(x) = \sum _{i=1} ^x [gcd (i, k)] = 1 f(x)=i=1x[gcd(i,k)]=1

S ( x , k ) = ∑ i = 1 x μ ( i ) [ g c d ( i , k ) = 1 ] S(x, k) = \sum _{i=1} ^x \mu (i) [gcd (i, k) = 1] S(x,k)=i=1xμ(i)[gcd(i,k)=1]


先看 f ( x ) f(x) f(x):若 g c d ( a , k ) = 1 gcd (a, k) = 1 gcd(a,k)=1,则 g c d ( a + n k , k ) = 1 gcd (a + nk, k) = 1 gcd(a+nk,k)=1。最后一段可能不满足,单独考虑。

f ( x ) = ⌊ x k ⌋ f ( k ) + f ( x % k ) f(x) = \lfloor \frac x k \rfloor f (k) + f (x \% k) f(x)=kxf(k)+f(x%k)

k ≤ 2000 k \le 2000 k2000,直接预处理计算。


S ( x , k ) = ∑ i = 1 x μ ( i ) [ g c d ( i , k ) = 1 ] = ∑ i = 1 x μ ( i ) ∑ d ∣ i , d ∣ k μ ( d ) = ∑ d ∣ k μ ( d ) ∑ d ∣ i μ ( i ) = ∑ d ∣ k μ ( d ) ∑ i = 1 x d μ ( i d ) \begin {aligned} S (x, k) & = \sum _{i=1} ^x \mu (i) [gcd (i, k) = 1] \\ & = \sum _{i=1} ^x \mu (i) \sum _{d \mid i, d \mid k} \mu (d) \\ &= \sum _{d \mid k} \mu (d) \sum _{d \mid i} \mu (i) \\ &= \sum _{d \mid k} \mu (d) \sum _{i=1} ^{\frac x d} \mu (id) \end {aligned} S(x,k)=i=1xμ(i)[gcd(i,k)=1]=i=1xμ(i)di,dkμ(d)=dkμ(d)diμ(i)=dkμ(d)i=1dxμ(id)

g c d ( i , d ) ̸ = 1 gcd (i, d) \not= 1 gcd(i,d)̸=1,则 μ ( i d ) = 0 \mu (id) = 0 μ(id)=0

S ( x , k ) = ∑ d ∣ k μ ( d ) ∑ i = 1 , g c d ( i , d ) = 1 x d μ ( i ) μ ( d ) = ∑ d ∣ k μ ( d ) 2 ∑ i = 1 , g c d ( i , d ) = 1 x d μ ( i ) = ∑ d ∣ k μ ( d ) 2 ∑ i = 1 x d μ ( i ) [ g c d ( i , d ) = 1 ] = ∑ d ∣ k μ ( d ) 2 S ( ⌊ x d ⌋ , d ) \begin {aligned} S(x, k) &= \sum _{d \mid k} \mu (d) \sum _{i=1, gcd (i, d) = 1} ^{\frac x d} \mu (i) \mu (d) \\ &= \sum _{d \mid k} \mu (d) ^2 \sum _{i=1, gcd (i, d) = 1} ^{\frac x d} \mu (i) \\ &= \sum _{d \mid k} \mu (d) ^2 \sum _{i=1} ^{\frac x d} \mu (i) [gcd (i, d) = 1] \\ &= \sum _{d \mid k} \mu (d) ^2 S (\lfloor \frac x d \rfloor, d) \end {aligned} S(x,k)=dkμ(d)i=1,gcd(i,d)=1dxμ(i)μ(d)=dkμ(d)2i=1,gcd(i,d)=1dxμ(i)=dkμ(d)2i=1dxμ(i)[gcd(i,d)=1]=dkμ(d)2S(dx,d)

k ≠ 1 k \neq 1 k̸=1,递归计算。

k = 1 k = 1 k=1 S ( x , k ) = ∑ i = 1 x μ ( i ) S(x, k) = \sum _{i=1} ^x \mu (i) S(x,k)=i=1xμ(i),杜教筛:

S ( n ) = ∑ i = 1 n μ ( i ) S(n) = \sum _{i=1} ^n \mu (i) S(n)=i=1nμ(i)

g ( 1 ) S ( n ) = ∑ i = 1 n ( g ∗ f ) ( i ) − ∑ i = 2 n g ( i ) S ( n i ) g(1)S(n) = \sum _{i=1} ^n (g * f) (i) - \sum _{i=2} ^n g(i) S(\frac n i) g(1)S(n)=i=1n(gf)(i)i=2ng(i)S(in)

g ( x ) = 1 g(x) = 1 g(x)=1

S ( n ) = 1 − ∑ i = 2 n S ( n i ) S(n) = 1 - \sum _{i=2} ^n S (\frac n i) S(n)=1i=2nS(in)


a n s = ∑ d = 1 n [ g c d ( d , k ) = 1 ] μ ( d ) ⌊ n d ⌋ ∑ j = 1 m d [ g c d ( j , k ) = 1 ] ans = \sum _{d = 1} ^n [gcd (d, k) = 1] \mu (d) \lfloor \frac n d \rfloor \sum _{j=1} ^{\frac m d} [gcd (j, k) = 1] ans=d=1n[gcd(d,k)=1]μ(d)dnj=1dm[gcd(j,k)=1]

前半部分记忆化,后半部分预处理 O ( 1 ) O(1) O(1)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll ;
typedef pair<int, int> P ;
const int maxn = 1e7 + 10 ;
int n, m, k ;
int prime[maxn], tot ;
int mu[maxn], summu[maxn], f[5010] ;
bool vis[maxn] ;
map<P, ll> ss ;
int gcd (int a, int b) {
    return b ? gcd (b, a % b) : a ;
}
void init() {
    for (int i = 1; i <= k; i ++)
        if (gcd (i, k) == 1) f[i] = 1 ;
    for (int i = 1; i <= k; i ++) f[i] += f[i - 1] ;
    mu[1] = 1 ;
    for (int i = 2; i < maxn; i ++) {
        if (!vis[i]) prime[++ tot] = i, mu[i] = -1 ;
        for (int j = 1; j <= tot && i * prime[j] < maxn; j ++) {
            vis[i * prime[j]] = 1 ;
            if (i % prime[j] == 0) {
                mu[i * prime[j]] = 0; break ;
            }
            mu[i * prime[j]] = -mu[i] ;
        }
    }
    for (int i = 1; i < maxn; i ++) summu[i] = summu[i - 1] + mu[i] ;
}
ll SS (int x, int k) {
    if ((!x) || (k == 1 && x < maxn)) return summu[x] ;
    if (ss[P (x, k)]) return ss[P (x, k)] ;
    ll res = 0 ;
    if (k == 1) {
        res = 1 ;
        for (int i = 2, j; i <= x; i = j + 1) {
            j = x / (x / i) ;
            res -= (j - i + 1) * SS (x / i, 1) ;
        }
    } else {
        for (int i = 1; i * i <= k; i ++) {
            if (k % i == 0) {
                if (mu[i]) res += SS (x / i, i) ;
                if (i * i != k && mu[k / i]) res += SS (x / (k / i), k / i) ;
            }
        }
    }
    return ss[P (x, k)] = res ;
}
ll SF (int x) {
    return 1ll * (x / k) * f[k] + f[x % k] ;
}
int main() {
    cin >> n >> m >> k ;
    init () ;
    ll ans = 0, pre = 0, cur ;
    for (int i = 1, j; i <= min (n, m); i = j + 1) {
        j = min (n / (n / i), m / (m / i)) ;
        cur = SS (j, k) ;
        ans += 1ll * (cur - pre) * (n / i) * SF (m / i) ;
        pre = cur ;
    }
    cout << ans << endl ;
    return 0 ;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值