ST Table、数论初步
Eva.Q Lv9

Co老师也太强了吧 !!!

ST 表

ST 表是基于 倍增 思想,用于解决 可重复贡献问题 的数据结构。

什么是可重复贡献问题?

可重复贡献问题 是指对于运算 ,满足 ,则对应的区间询问就是一个可重复贡献问题。例如,max , gcd,所以区间最大值或最小值、区间 GCD 就是一个可重复贡献问题。可重复地意思是指,假设已经知道了一个区间的两个子区间(可重叠)的答案,且这两个子区间的并集包含该区间,则可由这两个子区间的答案,快速计算出该区间的答案。像区间和就不具有这个性质,如果求区间和的时候采用的预处理区间重叠了,则会导致重叠部分被计算两次。另外, 还必须满足结合律 才能使用 ST 表求解。

综上想要使用 ST 表,需具备以下条件:

  1. 区间重叠不影响答案的正确性
例1

来看一道模板题吧~

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

解1

补充常识:

mx[i][j] 的含义:起点为 ,长度为 的区间的最大值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <bits/stdc++.h>
#include <algorithm>
#include <cmath>
#include <cstdio>
#define N 100008
using namespace std;

int mx[N][20];

inline int read()
{
int x = 0,f = 1;
char ch = getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}

inline int getmx(int l, int r){
int len = r - l + 1;
int t = (int)log2(len);
return max(mx[l][t], mx[r - (1 << (t)) + 1][t]);
}

int main(){
int n, m;
n = read(); m = read();
for(int i = 1; i <= n; ++i) mx[i][0] = read();
for(int j = 1; j <= log2(n); ++j)
for(int i = 1; i <= n - pow(2, j) + 1; ++i)
mx[i][j] = max(mx[i][j - 1], mx[i + (1 << (j - 1))][j - 1]);
while(m--){
int l = read();
int r = read();
printf("%d\n", getmx(l, r));
}
return 0;
}

数论初步 (约数相关)

素数与合数

素数 的约数只有

既不是素数,也不是合数

算数基本定理
内容

如果不考虑排列次序的话,每个大于1的自然数都只能有一种方式分解成若干个(大于等于 1 个)素数的乘积。

性质

1.(存在性)每个大于 1 的自然数都可以分解成素数的乘积。

2.(唯一 性)这种分解,再不考虑排列次序的意义下,是唯一的。

约数与倍数

对于 如果 的公约数。对于其中最大的 ,称 的最大公约数,记为

对于 如果 的公倍数。对于其中最小的 ,称 的最小公倍数,记为

集合含义

GCD

LCM

除法

对于整数 ,存在唯一的两个整数 使得:

带余除法

=

整除

记做 ,此时也称 的倍数, 的约数。

性质

一些常用的复杂度常识

素数分布:

调和级数:

  • Post title:ST Table、数论初步
  • Post author:Eva.Q
  • Create time:2021-08-19 09:56:02
  • Post link:https://qyy/2021/08/19/Algorithm/ColinClass3/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.