数学知识-数论分块

整数分块

∑ i = 1 n ⌊ n i ⌋ \sum_{i=1}^{n}\left\lfloor\frac{n}{i}\right\rfloor i=1nin

性质1:分块的块数<= 2 ⌊ n ⌋ 2\left\lfloor\sqrt{n}\right\rfloor 2n

i < = ⌊ n ⌋ i<=\left\lfloor{\sqrt{n}}\right\rfloor i<=n 时, ⌊ n l ⌋ \lfloor\frac{n}{l}\rfloor ln ⌊ n ⌋ \lfloor{\sqrt{n}}\rfloor n 种取法

i > ⌊ n ⌋ i>\lfloor\sqrt{n}\rfloor i>n 时, ⌊ n i ⌋ < = ⌊ n ⌋ \lfloor\sqrt{\frac{n}{i}}\rfloor<=\lfloor\sqrt{n}\rfloor in <=n ,最多也是 n 种 \sqrt{n}种 n 取法

性质2:l所在块的右端点为 ⌊ n ⌊ n l ⌋ ⌋ \left\lfloor{\frac{n}{\left\lfloor{\frac{n}{l}}\right\rfloor}}\right\rfloor lnn

[CQOI2007] 余数求和

题目描述

https://www.luogu.com.cn/problem/P2261

给出正整数 n n n k k k,请计算

G ( n , k ) = ∑ i = 1 n k   m o d   i G(n, k) = \sum_{i = 1}^n k \bmod i G(n,k)=i=1nkmodi

其中 k   m o d   i k\bmod i kmodi 表示 k k k 除以 i i i 的余数。

输入格式

输入只有一行两个整数,分别表示 n n n k k k

输出格式

输出一行一个整数表示答案。

样例 #1

样例输入 #1

10 5

样例输出 #1

29

提示

样例 1 解释

G ( 10 , 5 ) = 0 + 1 + 2 + 1 + 0 + 5 + 5 + 5 + 5 + 5 = 29 G(10, 5)=0+1+2+1+0+5+5+5+5+5=29 G(10,5)=0+1+2+1+0+5+5+5+5+5=29

数据规模与约定

  • 对于 30 % 30\% 30% 的数据,保证 n , k ≤ 1 0 3 n , k \leq 10^3 n,k103
  • 对于 60 % 60\% 60% 的数据,保证 n , k ≤ 1 0 6 n, k \leq 10^6 n,k106
  • 对于 100 % 100\% 100% 的数据,保证 1 ≤ n , k ≤ 1 0 9 1 \leq n, k \leq 10^9 1n,k109

代码

#include 

using namespace std;
#define int long  long

signed main() {
#ifndef ONLINE_JUDGE
    freopen("../test.in", "r", stdin);
    freopen("../test.out", "w", stdout);
#endif
    int n, k;
    cin >> n >> k;
    int res = n * k;
    int r;
    for (int l = 1; l <= n; l = r + 1) {
        if (k / l == 0) break;
        r = min(k / (k / l), n);
        res -= (k / l) * (r - l + 1) * (l + r) / 2;
    }
    cout << res;
    return 0;
}

Strange Function

https://www.luogu.com.cn/problem/CF1542C

题面翻译

f ( i ) f(i) f(i) 为最小的正整数数 x x x 满足 x x x 不是 i i i 的因子。

现给出正整数 n n n,请计算出 ∑ i = 1 n f ( i ) \sum_{i=1}^n f(i) i=1nf(i) 1 0 9 + 7 10^9+7 109+7 的值。上述式子等价于 f ( 1 ) + f ( 2 ) + ⋯ + f ( n ) f(1)+f(2)+\cdots+f(n) f(1)+f(2)++f(n)

本题含多组数据。令数据组数为 t t t,那么有 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1t104 1 ≤ n ≤ 1 0 16 1 \leq n \leq 10^{16} 1n1016

题目描述

Let $ f(i) $ denote the minimum positive integer $ x $ such that $ x $ is not a divisor of $ i $ .

Compute $ \sum_{i=1}^n f(i) $ modulo $ 10^9+7 $ . In other words, compute $ f(1)+f(2)+\dots+f(n) $ modulo $ 10^9+7 $ .

输入格式

The first line contains a single integer $ t $ ( $ 1\leq t\leq 10^4 $ ), the number of test cases. Then $ t $ cases follow.

The only line of each test case contains a single integer $ n $ ( $ 1\leq n\leq 10^{16} $ ).

输出格式

For each test case, output a single integer $ ans $ , where $ ans=\sum_{i=1}^n f(i) $ modulo $ 10^9+7 $ .

样例 #1

样例输入 #1

6
1
2
3
4
10
10000000000000000

样例输出 #1

2
5
7
10
26
366580019

提示

In the fourth test case $ n=4 $ , so $ ans=f(1)+f(2)+f(3)+f(4) $ .

  • $ 1 $ is a divisor of $ 1 $ but $ 2 $ isn’t, so $ 2 $ is the minimum positive integer that isn’t a divisor of $ 1 $ . Thus, $ f(1)=2 $ .
  • $ 1 $ and $ 2 $ are divisors of $ 2 $ but $ 3 $ isn’t, so $ 3 $ is the minimum positive integer that isn’t a divisor of $ 2 $ . Thus, $ f(2)=3 $ .
  • $ 1 $ is a divisor of $ 3 $ but $ 2 $ isn’t, so $ 2 $ is the minimum positive integer that isn’t a divisor of $ 3 $ . Thus, $ f(3)=2 $ .
  • $ 1 $ and $ 2 $ are divisors of $ 4 $ but $ 3 $ isn’t, so $ 3 $ is the minimum positive integer that isn’t a divisor of $ 4 $ . Thus, $ f(4)=3 $ .

Therefore, $ ans=f(1)+f(2)+f(3)+f(4)=2+3+2+3=10 $ .

思路

因为 f [ i ] = x f[i]=x f[i]=x,即 x x x是最小的不可以被 i i i整除的数,那么 1 , 2 , 3... x − 1 1,2,3...x-1 1,2,3...x1一定都是可以被 i i i整除的

因此 i 可以整除 l c m ( 1 , 2 , 3... x − 1 ) i可以整除lcm(1,2,3...x-1) i可以整除lcm(1,2,3...x1),并且 i 不可以整除 l c m ( 1 , 2 , 3.... x − 1 , x ) . i不可以整除lcm(1,2,3....x-1,x). i不可以整除lcm(1,2,3....x1,x).

因为 f [ i ] = x f[i]=x f[i]=x,这里的 x x x不会很大,估计不超过80,可以打表算一下 x = l c m ( 1 , 2 , 3.. ) x=lcm(1,2,3..) x=lcm(1,2,3..)

所以我们可以考虑使用数论分块的思想,根据 x x x的值,算有多少个数,满足 f [ i ] = x f[i]=x f[i]=x.,假设有 n u m num num个,那么对答案的贡献就是 n u m ∗ x num*x numx

如何算有多少个呢?等于满足条件的数-不满足条件的数

n u m = n l c m ( 1 , 2 , 3... x − 1 ) − n l c m ( 1 , 2 , 3... x ) num=\frac{n}{lcm(1,2,3...x-1)}-\frac{n}{lcm(1,2,3...x)} num=lcm(1,2,3...x1)nlcm(1,2,3...x)n

t = l c m ( 1 , 2 , 3... x − 1 ) t=lcm(1,2,3...x-1) t=lcm(1,2,3...x1)

n u m = n t − n l c m ( t , i ) num=\frac{n}{t}-\frac{n}{lcm(t,i)} num=tnlcm(t,i)n

代码

#include 

#define int long long
#define yes cout << "YES" << endl;
#define no cout << "NO" << endl;
#define IOS cin.tie(0), cout.tie(0), ios::sync_with_stdio(false);
#define cxk 1
#define debug(s, x) if (cxk) cout << "#debug:(" << s << ")=" << x << endl;
using namespace std;

const int mod = 1e9 + 7;

void solve() {
    int n;
    cin >> n;
    int res = 0;
    int cur = 1;
    for (int i = 2;; i++) {
        int t = i * (n / cur - n / lcm(cur, i));
        t %= mod;
        res = (res + t) % mod;
        cur = lcm(cur, i);
        if (cur > n) break;
    }
    cout << res << endl;
}

signed main() {
    IOS
#ifndef ONLINE_JUDGE
    freopen("../test.in", "r", stdin);
    freopen("../test.out", "w", stdout);
#endif
    int _ = 1;
    cin >> _;
    while (_--) solve();
    return 0;
}

你可能感兴趣的:(ACM-,ICPC,#,数学知识,算法,c++)