前言

2024-11-19整理旧电脑是偶然发现以前留的模板代码。

唏嘘啊,有的都记不起干什么的了。

通用模板

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
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

signed main() {
return 0;
}

2-SAT

洛谷P4782

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 1e6 + 9;
int n, m, dfn[N << 1], low[N << 1], scc[N << 1], stk[N << 1], vis[N << 1], stktop, scccnt, dfncnt;
vector<int> G[N << 1];
void tarjan(int x) {
dfn[x] = low[x] = ++dfncnt;
vis[x] = 1;
stk[++stktop] = x;
for (auto val : G[x]) {
if (!dfn[val]) {
tarjan(val);
low[x] = min(low[val], low[x]);
}
else if (vis[val]) low[x] = min(low[val], low[x]);
}
if (low[x] == dfn[x]) {
++scccnt;
vis[x] = 0;
scc[x] = scccnt;
while (stk[stktop] != x) {
vis[stk[stktop]] = 0;
scc[stk[stktop--]] = scccnt;
}
--stktop;
}
return;
}

signed main() {
read(n, m);
while (m--) {
int i, j, a, b;
read(i, a, j, b);
if (a && b) {
G[i + n].push_back(j);
G[j + n].push_back(i);
}
else if (!a && !b) {
G[i].push_back(j + n);
G[j].push_back(i + n);
}
else if (!a && b) {
G[i].push_back(j);
G[j + n].push_back(i + n);
}
else {
G[j].push_back(i);
G[i + n].push_back(j + n);
}
}
for (int i = 1; i <= (n << 1); ++i) {
if (!dfn[i]) tarjan(i);
}
int flag = 0;
for (int i = 1; i <= n; ++i) {
flag |= scc[i] == scc[i + n];
}
if (flag) puts("IMPOSSIBLE");
else {
puts("POSSIBLE");
for (int i = 1; i <= n; ++i) {
print(scc[i] < scc[i + n] ? 1 : 0), putchar(' ');
}
}
return 0;
}

AC自动机

洛谷P3796

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 2e4 + 9, M = 1e6 + 9, E = 159;

int n, endpos[E];
char t[E][71], s[M];
struct NODE{
int son[26], fail, cnt, in;
}trie[N];
int cnt, que[N];
void Init() {
cnt = 1;
memset(trie, 0, sizeof(trie));
for (register int p = 1; p <= n; ++p) {
scanf("%s", t[p]);
register int len = strlen(t[p]), now = 1;
for (register int i = 0; i < len; ++i) {
if (!trie[now].son[t[p][i] - 'a']) trie[now].son[t[p][i] - 'a'] = ++cnt;
now = trie[now].son[t[p][i] - 'a'];
}
endpos[p] = now;
}
trie[1].fail = 1;
register int T = 0, H = 0;
for (register int i = 0; i < 26; ++i) {
if (!trie[1].son[i]) trie[1].son[i] = 1;
else que[++H] = trie[1].son[i], trie[trie[1].son[i]].fail = 1;
}
while (T < H) {
register int now = que[++T], fail = trie[now].fail;
for (register int i = 0, s = 0; i < 26; ++i) {
s = trie[now].son[i];
if (!s) trie[now].son[i] = trie[fail].son[i];
else que[++H] = s, trie[s].fail = trie[fail].son[i], ++trie[trie[fail].son[i]].in;
}
}
return;
}
void deal() {
scanf("%s", s);
register int lens = strlen(s), now = 1;
for (register int i = 0; i < lens; ++i) {
now = trie[now].son[s[i] - 'a'];
++trie[now].cnt;
}
register int H = 0, T = 0;
for (register int i = 1; i <= cnt; ++i) {
if (!trie[i].in) que[++H] = i;
}
while (T < H) {
register int now = que[++T];
trie[trie[now].fail].cnt += trie[now].cnt;
--trie[trie[now].fail].in;
if (!trie[trie[now].fail].in) que[++H] = trie[now].fail;
}
register int m = 0;
for (register int i = 1; i <= n; ++i) {
m = max(trie[endpos[i]].cnt, m);
}
print(m), puts("");
for (register int i = 1; i <= n; ++i) {
if (trie[endpos[i]].cnt == m) printf("%s\n", t[i]);
}
return;
}

signed main() {
while (read(n), n) {
Init();
deal();
}
return 0;
}

KMP

洛谷P3375

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
39
40
41
42
43
44
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 2e6 + 9;
int lens, lent, nex[N];
char s[N], t[N];

signed main() {
scanf("%s", s + 1);
scanf("%s", t + 1);
lens = strlen(s + 1);
lent = strlen(t + 1);
for (register int i = 2, j = 0; i <= lent; ++i) {
while (j && t[j + 1] != t[i]) j = nex[j];
if (t[j + 1] == t[i]) ++j;
nex[i] = j;
}
for (register int i = 1, j = 0; i <= lens; ++i) {
while (j && t[j + 1] != s[i]) j = nex[j];
if (t[j + 1] == s[i]) ++j;
if (j == lent) printf("%d\n", i - j + 1), j = nex[j];
}
for (register int i = 1; i <= lent; ++i) printf("%d%c", nex[i], " \n"[i == lent]);
return 0;
}

LCA(树剖)

洛谷P3379

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}
const int N = 5e5 + 9;
int size[N], dep[N], fa[N], son[N], top[N], n, m, s;
vector<int> G[N];
void dfs1(int x, int f) {
fa[x] = f;
dep[x] = dep[f] + 1;
size[x] = 1;
for (auto val : G[x]) {
if (val == f) continue;
dfs1(val, x);
size[x] += size[val];
son[x] = size[val] > size[son[x]] ? val : son[x];
}
return;
}
void dfs2(int x, int topf) {
top[x] = topf;
if (!son[x]) return;
dfs2(son[x], topf);
for (auto val : G[x]) {
if (val == son[x] || val == fa[x]) continue;
dfs2(val, val);
}
return;
}
int LCA(int x, int y) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
x = fa[top[x]];
}
return dep[x] > dep[y] ? y : x;
}

signed main() {
read(n, m, s);
for (register int i = 1, x = 0, y = 0; i < n; ++i) {
read(x, y);
G[x].push_back(y);
G[y].push_back(x);
}
dfs1(s, 0);
dfs2(s, s);
register int a = 0, b = 0;
while (m--) {
read(a, b);
print(LCA(a, b)), puts("");
}
return 0;
}

Manacher

洛谷P3805

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
39
40
41
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 11000009;
int len, ans, e[N << 1];
char T[N << 1];

signed main() {
T[0] = '~', T[len = 1] = '|';
char c = getchar();
while (c < 'a' || c > 'z') c = getchar();
while (c >= 'a' && c <= 'z') T[++len] = c, T[++len] = '|', c = getchar();
for (int i = 1, mid = 0, r = 0; i <= len; ++i) {
if (i <= r && mid) e[i] = min(e[(mid << 1) - i], r - i + 1); // 由对称性可得,min右边的那一项是因为原来的2*mid-i可能统计了超过一mid为中心的回文串的边缘
// 而min为中心的回文串左右并不一样,所以要加min(r-i+1)
while (T[i - e[i]] == T[e[i] + i]) ++e[i];//暴力扩展
if (e[i] + i > r) mid = i, r = e[i] + i - 1;//更新最右端
if (ans < e[i]) ans = e[i];//更新答案
}
print(ans - 1);
return 0;
}

SPFA

洛谷P3385

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 2e3 + 9, M = 3e3 + 9;
struct EDGE{int to, val;};
vector<EDGE> G[N];
queue<int> Q;
int dis[N], vis[N], cnt[N], T, n, m;

bool SPFA() {
memset(dis, 0x3f, sizeof(dis));
memset(vis, 0, sizeof(vis));
memset(cnt, 0, sizeof(cnt));
while (!Q.empty()) Q.pop();
dis[1] = 0, vis[1] = 1;
Q.push(1);
while (!Q.empty()) {
int now = Q.front();
Q.pop();vis[now] = 0;
for (auto val : G[now]) {
if (dis[now] + val.val < dis[val.to]) {
dis[val.to] = dis[now] + val.val;
cnt[val.to] = cnt[now] + 1;
if (cnt[val.to] >= n) return false;
if (!vis[val.to]) Q.push(val.to), vis[val.to] = 1;
}
}
}
return true;
}

signed main() {
read(T);
while (T--) {
read(n, m);
for (int i = 1; i <= n; ++i) {
G[i].clear();
}
for (int i = 1, u = 0, v = 0, w = 0; i <= m; ++i) {
read(u, v, w);
G[u].push_back((EDGE){v, w});
if (w >= 0) G[v].push_back((EDGE){u, w});
}
puts(SPFA() ? "NO" : "YES");
}
return 0;
}

ST表

洛谷P3865

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
39
40
41
42
43
44
45
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 1e5 + 9;
int st[N][20], rec[N], n, m;

signed main() {
read(n, m);
rec[0] = -1;
for (register int i = 1; i <= n; ++i) {
read(st[i][0]);
rec[i] = rec[i >> 1] + 1;
}
for (register int k = 1; (1 << k) <= n; ++k) {
for (register int i = 1; i + (1 << k) - 1 <= n; ++i) {
st[i][k] = max(st[i][k - 1], st[i + (1 << (k - 1))][k - 1]);
}
}
register int l = 0, r = 0, k = 0;
while (m--) {
read(l, r);
k = rec[r - l + 1];
print(max(st[l][k], st[r - (1 << k) + 1][k])), puts("");
}
return 0;
}

差分约束

洛谷P5960

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 5e3 + 9;
struct EDGE{int to, val;};
vector<EDGE> G[N];
queue<int> Q;
int dis[N], vis[N], cnt[N], n, m;
bool SPFA() {
memset(dis, 0x3f, sizeof(dis));
vis[n + 1] = 1, dis[n + 1] = 0;
Q.push(n + 1);
while (!Q.empty()) {
int x = Q.front();
Q.pop(); vis[x] = 0;
for (auto val : G[x]) {
if (dis[x] + val.val < dis[val.to]) {
dis[val.to] = dis[x] + val.val;
cnt[val.to] = cnt[x] + 1;
if (cnt[val.to] >= n + 1) return false;
if (!vis[val.to]) vis[val.to] = 1, Q.push(val.to);
}
}
}
return true;
}

signed main() {
read(n, m);
for (int i = 1, u = 0, v = 0, w = 0; i <= m; ++i) {
read(u, v, w);
G[v].push_back((EDGE){u, w});
}
for (int i = 1; i <= n; ++i) {
G[n + 1].push_back((EDGE){i, 0});
}
if (!SPFA()) puts("NO");
else {
for (int i = 1; i <= n; ++i) {
print(dis[i]), putchar(' ');
}
}
return 0;
}

单源最短路径(Dijkstra)

洛谷P4779

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 1e5 + 9, M = 2e5 + 9, INF = 2e9 + 7;
int head[N], nex[M], to[M], w[M], cnt;
int n, m, s;
int dis[N], vis[N];
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > H;

void add_edge(int u, int v, int val) {
nex[++cnt] = head[u];
to[cnt] = v;
w[cnt] = val;
head[u] = cnt;
}

signed main() {
read(n, m, s);
for (register int i = 1, u = 0, v = 0, w = 0; i <= m; ++i) {
read(u, v, w);
add_edge(u, v, w);
}
for (register int i = 1; i <= n; ++i) {
dis[i] = INF;
}
dis[s] = 0;
H.push(make_pair(0, s));
while (!H.empty()) {
int now = H.top().second;
H.pop();
if (vis[now]) continue;
vis[now] = 1;
for (register int i = head[now]; i; i = nex[i]) {
if (dis[now] + w[i] < dis[to[i]]) {
dis[to[i]] = dis[now] + w[i];
H.push(make_pair(dis[to[i]], to[i]));
}
}
}
for (register int i = 1; i <= n; ++i) printf("%d%c", dis[i], " \n"[i == n]);
return 0;
}

笛卡尔树

洛谷P5854

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
39
40
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 1e7 + 9;
long long n, lans, rans;
long long stk[N], val[N], lson[N], rson[N];

signed main() {
read(n);
for (int i = 1, top = 0; i <= n; ++i) {
read(val[i]);
int pos = top;
while (pos && val[stk[pos]] > val[i]) --pos;
if (pos) rson[stk[pos]] = i;
if (pos < top) lson[i] = stk[pos + 1];
stk[top = ++pos] = i;
}
for (int i = 1; i <= n; ++i) lans ^= i * (lson[i] + 1), rans ^= i * (rson[i] + 1);
print(lans), putchar(' '), print(rans);
return 0;
}

点分治

洛谷P3806

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 1e4 + 9, M = 109, INF = 1e7 + 9;
struct EDGE{int to, val;};
vector<EDGE> G[N];
int n, m;
int root, reccnt, nowsize, ms[N], vis[N], dis[N], size[N], rec[N], book[INF], res[M], que[M], clr[N];

void getroot(int x, int f) {
size[x] = 1, ms[x] = 0;
for (auto w : G[x]) {
if (w.to == f || vis[w.to]) continue;
getroot(w.to, x);
size[x] += size[w.to];
ms[x] = max(ms[x], size[w.to]);
}
ms[x] = max(nowsize - size[x], ms[x]);
if (ms[x] < ms[root]) root = x;
return;
}

void getdis(int x, int f) {
rec[++reccnt] = dis[x];
for (auto w : G[x]) {
if (w.to == f || vis[w.to]) continue;
dis[w.to] = dis[x] + w.val;
getdis(w.to, x);
}
return;
}

void solve(int x) {
int clrcnt = 0;
for (auto w : G[x]) {
if (vis[w.to])continue;
reccnt = 0, dis[w.to] = w.val;
getdis(w.to, x);
for (int i = 1; i <= reccnt; ++i) {
for (int j = 1; j <= m; ++j) {
if (que[j] >= rec[i])res[j] |= book[que[j] - rec[i]];
}
}
for (int i = 1; i <= reccnt; ++i) {
if (rec[i] <= 1e7) clr[++clrcnt] = rec[i], book[rec[i]] = 1;
}
}
for (int i = 1; i <= clrcnt; ++i) book[clr[i]] = 0;
return;
}

void divide(int x) {
vis[x] = 1, book[0] = 1;
solve(x);
for (auto w : G[x]) {
if (vis[w.to]) continue;
root = 0, ms[0] = INF;
nowsize = size[w.to];
getroot(w.to, x);
divide(root);
}
return;
}

signed main() {
read(n, m);
for (int i = 1, u = 0, v = 0, w = 0; i < n; ++i) {
read(u, v, w);
G[u].push_back((EDGE){v, w});
G[v].push_back((EDGE){u, w});
}
for (int i = 1; i <= m; ++i) {
read(que[i]);
}
ms[0] = INF, root = 0;
getroot(1, 0);
divide(root);
for (int i = 1; i <= m; ++i) {
puts(res[i] ? "AYE" : "NAY");
}
return 0;
}

点双分量

洛谷P3388

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 2e4 + 9, M = 1e5 + 9;

int dfn[N], low[N], cut[N], tarcnt, n, m, ans;
vector<int> G[N];

void tarjan(int now, int fa) {
dfn[now] = low[now] = ++tarcnt;
register int chd = 0;
for (auto val : G[now]) {
if (val == fa) continue;
if (!dfn[val]) {
++chd;
tarjan(val, now);
low[now] = min(low[now], low[val]);
if (low[val] >= dfn[now]) cut[now] = 1;
}
else low[now] = min(low[now], dfn[val]);
}
if (chd == 1 && fa == 0) cut[now] = 0;
return;
}

signed main() {
read(n, m);
for (register int i = 1, u = 0, v = 0; i <= m; ++i) {
read(u, v);
G[u].push_back(v);
G[v].push_back(u);
}
for (register int i = 1; i <= n; ++i) {
if (!dfn[i]) tarjan(i, 0);
if (cut[i]) ++ans;
}
print(ans), puts("");
for (register int i = 1; i <= n; ++i) {
if (cut[i]) print(i), putchar(' ');
}
return 0;
}

二分图最大匹配

洛谷P3386

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const long long INF = 7435234564764323;
const int N = 1009, M = 5e4 + 9;
int n, m, e, s, t, head[N], pre[N], level[N], que[N], cnt = 1;
long long ans;
struct EDGE{int to, nex;long long flow;}edge[(N + M) << 1];

long long dfs(int x, long long rest){
if (x == t) return rest;
register long long flow = 0, f = 0;
for (int &i = pre[x]; i; i = edge[i].nex) {
if (level[x] + 1 == level[edge[i].to] && edge[i].flow) {
f = dfs(edge[i].to, min(rest - flow, edge[i].flow));
flow += f, edge[i].flow -= f, edge[i ^ 1].flow += f;
}
}
if (!flow) level[x] = 0;
return flow;
}

int bfs() {
memset(level, 0, sizeof(level));
register int H = 1, T = 0; que[1] = s, level[s] = 1;
while (T < H) {
int now = que[++T];
for (register int i = head[now]; i; i = edge[i].nex) {
if (!level[edge[i].to] && edge[i].flow) {
level[edge[i].to] = level[now] + 1;
que[++H] = edge[i].to;
}
}
}
return level[t];
}

void dinic() {
while (bfs()) {
for (register int i = 1; i <= n; ++i) pre[i] = head[i];
ans += dfs(s, INF);
}
return;
}


signed main() {
read(m, n, e);
n += m;
s = n + 1, t = n + 2;
for (register int i = 1, u = 0, v = 0; i <= e; ++i) {
read(u, v);
v += m;
edge[++cnt] = (EDGE){v, head[u], 1}, head[u] = cnt;
edge[++cnt] = (EDGE){u, head[v], 0}, head[v] = cnt;
}
for (register int i = 1; i <= m; ++i) {
edge[++cnt] = (EDGE){i, head[s], 1}, head[s] = cnt;
edge[++cnt] = (EDGE){s, head[i], 0}, head[i] = cnt;
}
for (register int i = m + 1; i <= n; ++i) {
edge[++cnt] = (EDGE){t, head[i], 1}, head[i] = cnt;
edge[++cnt] = (EDGE){i, head[t], 0}, head[t] = cnt;
}
n += 2;
dinic();
print(ans);
return 0;
}

三分法

洛谷P3382

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <iostream>
#include <iomanip>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

#define eps 1e-7
int n;
double l, r;
double x[14];


double f(double t) {
double ans = 0;
for (int i = 0; i <= n; ++i) {
double e = 1;
for (int j = 1; j <= i; ++j) e *= t;
ans += e * x[i];
}
return ans;
}

signed main() {
cin >> n >> l >> r;
for (int i = n; i >= 0; --i) {
cin >> x[i];
}
double lmid = l + (r - l) / 3, rmid = r - (r - l) / 3;
while (rmid - lmid > eps) {
double lv = f(lmid), rv = f(rmid);
if (lv > rv) r = rmid;
else l = lmid;
lmid = l + (r - l) / 3, rmid = r - (r - l) / 3;
}
cout << fixed << setprecision(5) << lmid;
return 0;
}

三维偏序

洛谷P3810

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}
const int N = 1e5 + 9, K = 2e5 + 9;;

struct NODE{int a, b, c, ans, cnt;}d[N], s[N], temp[N];
bool cmod1(NODE a, NODE b) {return a.a == b.a ? (a.b == b.b ? a.c < b.c : a.b < b.b) : a.a < b.a;}
int n, k, cnt, tree[K], ans[N];
void add(int pos, int val) {
for (register int i = pos; i <= k; i += i & (-i)) {
tree[i] += val;
}
return;
}
int query(int pos) {
register int ans = 0;
for (register int i = pos; i >= 1; i -= i & (-i)) {
ans += tree[i];
}
return ans;
}
void CDQ(int l, int r) {
if (l == r) return;
register int mid = (l + r) >> 1;
CDQ(l, mid); CDQ(mid + 1, r);
register int p = l, q = mid + 1, t = l;
while (p <= mid && q <= r) {
if (d[p].b <= d[q].b) {
add(d[p].c, d[p].cnt);
temp[t++] = d[p++];
}
else {
d[q].ans += query(d[q].c);
temp[t++] = d[q++];
}
}
while (q <= r) d[q].ans += query(d[q].c), temp[t++] = d[q++];
for (register int i = l; i < p; ++i) add(d[i].c, -d[i].cnt);
while (p <= mid) temp[t++] = d[p++];
for (register int i = l; i <= r; ++i) d[i] = temp[i];
return;
}

signed main() {
read(n, k);
for (register int i = 1; i <= n; ++i) {
read(s[i].a, s[i].b, s[i].c);
}
sort(s + 1, s + 1 + n, cmod1);
for (register int i = 1; i <= n; ++i) {
d[++cnt] = (NODE){s[i].a, s[i].b, s[i].c, 0, 1};
while (i < n && s[i].a == s[i + 1].a && s[i].b == s[i + 1].b && s[i].c == s[i + 1].c) ++d[cnt].cnt, ++i, ++d[cnt].ans;
}
CDQ(1, cnt);
for (register int i = 1; i <= cnt; ++i) {
ans[d[i].ans] += d[i].cnt;
}
for (register int i = 0; i < n; ++i) {
print(ans[i]), puts("");
}
return 0;
}

树状数组

洛谷P3374

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 5e5 + 9;
int n, m;
long long tree[N];
long long ask(int pos) {
long long ans = 0;
for (register int i = pos; i >= 1; i -= i & (-i)) {
ans += tree[i];
}
return ans;
}
void modify(int pos, long long val) {
for (register int i = pos; i <= n; i += i & (-i)) {
tree[i] += val;
}
return;
}

signed main() {
read(n, m);
for (register int i = 1, val = 0; i <= n; ++i) {
read(val);
modify(i, val);
}
register int x = 0, y = 0, opt = 0;
register long long k = 0;
while (m--) {
read(opt);
if (opt == 1) {
read(x, k);
modify(x, k);
}
else {
read(x, y);
print(ask(y) - ask(x - 1)), puts("");
}
}
return 0;
}

缩点

洛谷P3387

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 1e4 + 9;
vector<int> G[N], Gscc[N], scc[N];
int scccnt, dfncnt, stktop, n, m, val[N], dfn[N], low[N], stk[N], vis[N], col[N], sccval[N], sccdeg[N], que[N], dp[N], head, tail;
void tarjan(int x) {
dfn[x] = low[x] = ++dfncnt;
stk[++stktop] = x;
vis[x] = 1;
for (auto val : G[x]) {
if (!dfn[val]) {
tarjan(val);
low[x] = min(low[x], low[val]);
}
else if (vis[val]) {
low[x] = min(low[x], low[val]);
}
}
if (low[x] == dfn[x]) {
col[x] = ++scccnt;
sccval[scccnt] += val[x];
vis[x] = 0;
while (stk[stktop] != x) {
vis[stk[stktop]] = 0;
sccval[scccnt] += val[stk[stktop]];
col[stk[stktop--]] = scccnt;
}
--stktop;
}
return;
}

signed main() {
read(n, m);
for (register int i = 1; i <= n; ++i) read(val[i]);
for (register int i = 1, x = 0, y = 0; i <= m; ++i){
read(x, y);
G[x].push_back(y);
}
for (register int i = 1; i <= n; ++i) {
if (!dfn[i]) {
tarjan(i);
}
}
for (register int i = 1; i <= n; ++i) {
for (auto val : G[i]) {
if (col[val] != col[i]) {
Gscc[col[i]].push_back(col[val]);
++sccdeg[col[val]];
}
}
}
for (register int i = 1; i <= scccnt; ++i) {
if (!sccdeg[i]) que[++head] = i;
}
while (tail < head) {
int now = que[++tail];
sccval[now] += dp[now];
for (auto val : Gscc[now]) {
dp[val] = max(dp[val], sccval[now]);
sccdeg[val]--;
if (!sccdeg[val]) que[++head] = val;
}
}
int ans = 0;
for (int i = 1; i <= scccnt; ++i) {
ans = max(sccval[i], ans);
}
print(ans);
return 0;
}

网络最大流

洛谷P3376

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const long long INF = 7435234564764323;
const int N = 209, M = 5009;
int n, m, s, t, head[N], pre[N], level[N], que[N], cnt = 1;
long long ans;
struct EDGE{int to, nex;long long flow;}edge[M << 1];

long long dfs(int x, long long rest){
if (x == t) return rest;
register long long flow = 0, f = 0;
for (int &i = pre[x]; i; i = edge[i].nex) {
if (level[x] + 1 == level[edge[i].to] && edge[i].flow) {
f = dfs(edge[i].to, min(rest - flow, edge[i].flow));
flow += f, edge[i].flow -= f, edge[i ^ 1].flow += f;
}
}
if (!flow) level[x] = 0;
return flow;
}

int bfs() {
memset(level, 0, sizeof(level));
register int H = 1, T = 0; que[1] = s, level[s] = 1;
while (T < H) {
int now = que[++T];
for (register int i = head[now]; i; i = edge[i].nex) {
if (!level[edge[i].to] && edge[i].flow) {
level[edge[i].to] = level[now] + 1;
que[++H] = edge[i].to;
}
}
}
return level[t];
}

void dinic() {
while (bfs()) {
for (register int i = 1; i <= n; ++i) pre[i] = head[i];
ans += dfs(s, INF);
}
return;
}


signed main() {
read(n, m, s, t);
for (register int i = 1, u = 0, v = 0, w = 0; i <= m; ++i) {
read(u, v, w);
edge[++cnt] = (EDGE){v, head[u], w}, head[u] = cnt;
edge[++cnt] = (EDGE){u, head[v], 0}, head[v] = cnt;
}
dinic();
print(ans);
return 0;
}

线段树

洛谷P3372

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 1e5 + 9;
struct SEGMENTTREE{
private:
struct NODE{
long long val, lz;
NODE *lson, *rson;
}tree[N << 1], *root;
int cnt, n;
void build(NODE *now, int l, int r, long long val[]) {
now->lz = 0;
if (l == r) {
now->val = val[l];
}
else {
int mid = (l + r) >> 1;
now->lson = &tree[++cnt], now->rson = &tree[++cnt];
build(now->lson, l, mid, val);
build(now->rson, mid + 1, r, val);
now->val = now->lson->val + now->rson->val;
}
}
void pushdown(NODE *now, int l, int r, int mid) {
if (!now->lz) return;
now->lson->val += now->lz * (mid - l + 1);
now->rson->val += now->lz * (r - mid);
now->lson->lz += now->lz;
now->rson->lz += now->lz;
now->lz = 0;
}
void update(NODE *now, int l, int r, int L, int R, long long val) {
if (L <= l && r <= R) {
now->val += val * (r - l + 1);
now->lz += val;
}
else {
int mid = (l + r) >> 1;
pushdown(now, l, r, mid);
if (L <= mid) update(now->lson, l, mid, L, R, val);
if (R > mid) update(now->rson, mid + 1, r, L, R, val);
now->val = now->lson->val + now->rson->val;
}
return;
}
long long query(NODE *now, int l, int r, int L, int R) {
if (L <= l && r <= R) {
return now->val;
}
else {
int mid = (l + r) >> 1;
pushdown(now, l, r, mid);
long long res = 0;
if (L <= mid) res += query(now->lson, l, mid, L, R);
if (R > mid) res += query(now->rson, mid + 1, r, L, R);
return res;
}
return 0;
}
public:
void Init(int size, long long val[]) {
n = size;
cnt = 0;
root = &tree[++cnt];
build(root, 1, n, val);
return;
}
long long ask(int l, int r) {
return query(root, 1, n, l, r);
}
void modify(int l, int r, long long val) {
update(root, 1, n, l, r, val);
return;
}
}S;
long long val[N];
int n, m;

signed main() {
read(n, m);
for (register int i = 1; i <= n; ++i) read(val[i]);
S.Init(n, val);
register int x = 0, y = 0, opt = 0;
register long long k = 0;
while (m--) {
read(opt);
if (opt == 1) {
read(x, y, k);
S.modify(x, y, k);
}
else {
read(x, y);
print(S.ask(x, y)), puts("");
}
}
return 0;
}

中国剩余定理(CRT)

洛谷P1495

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
39
40
41
42
43
44
45
46
47
48
49
50
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

long long exgcd(long long a, long long b, long long &x, long long &y) {
if (!b) {
x = 1, y = 0;
return a;
}
long long t = exgcd(b, a % b, x, y), k = x;
x = y;
y = k - a / b * y;
return t;
}

int n;
long long a[11], b[11], inv[11], M = 1, ans;

signed main() {
read(n);
for (register int i = 1; i <= n; ++i) {
read(b[i], a[i]);
M *= b[i];
}
for (register int i = 1; i <= n; ++i) {
long long m = M / b[i], x = 0, y = 0;
exgcd(m, b[i], x, y);
ans = (ans + a[i] * m % M * x) % M;
}
print((ans + M) % M);
return 0;
}

主席树

洛谷P3834

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 2e5 + 9;
int n, m, tot, disc[N], num[N];
struct NODE {
NODE *lson, *rson;
int val;
}tree[N << 5], *his[N];
int cnt;
void build(NODE *now, int l, int r) {
if (l != r) {
int mid = (l + r) >> 1;
now->lson = &tree[++cnt], now->rson = &tree[++cnt];
build(now->lson, l, mid);
build(now->rson, mid + 1, r);
}
return;
}
void insert(NODE *last, NODE *now, int l, int r, int pos, int val) {
if (l == r) {
now->val = last->val + val;
}
else {
int mid = (l + r) >> 1;
if (pos <= mid) {
now->rson = last->rson;
now->lson = &tree[++cnt];
insert(last->lson, now->lson, l, mid, pos, val);
}
else {
now->lson = last->lson;
now->rson = &tree[++cnt];
insert(last->rson, now->rson, mid + 1, r, pos, val);
}
now->val = now->lson->val + now->rson->val;
}
return;
}
int ask(NODE *L, NODE *R, int l,int r, int k) {
if (l == r) return l;
else {
int mid = (l + r) >> 1;
if (R->lson->val - L->lson->val >= k) {
return ask(L->lson, R->lson, l, mid, k);
}
else {
return ask(L->rson, R->rson, mid + 1, r, k - (R->lson->val - L->lson->val));
}
}
return 0;
}

signed main() {
read(n, m);
for (int i = 1; i <= n; ++i) {
read(num[i]);
disc[i] = num[i];
}
sort(disc + 1, disc + 1 + n);
tot = unique(disc + 1, disc + 1 + n) - disc - 1;
his[0] = &tree[++cnt];
build(his[0], 1, tot);
for (int i = 1; i <= n; ++i) {
num[i] = lower_bound(disc + 1, disc + 1 + tot, num[i]) - disc;
his[i] = &tree[++cnt];
insert(his[i - 1], his[i], 1, tot, num[i], 1);
}
int l = 0, r = 0, k = 0;
while (m--) {
read(l, r, k);
print(disc[ask(his[l - 1], his[r], 1, tot, k)]), puts("");
}
return 0;
}

最小表示法

洛谷P1368

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
39
40
41
42
43
44
45
46
47
48
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 3e5 + 9;
int val[N << 1], n;

signed main() {
read(n);
for (int i = 1; i <= n; ++i) {
read(val[i]);
val[i + n] = val[i];
}
int p = 1, q = 2, k = 0;
while (p <= n && q <= n) {
for (k = 0; k < n && val[p + k] == val[q + k]; ++k);
if (k == n) break;
if (val[p + k] > val[q + k]) {
p += k + 1;
if (p == q) ++p;
}
else {
q += k + 1;
if (p == q) ++q;
}
}
p = min(p, q), q = p + n - 1;
for (;p <= q; ++p) print(val[p]), putchar(' ');
return 0;
}

最小生成树

洛谷P3366

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
template <typename T> inline void read(T &x) {
T f = 1, ch = getchar(); x = 0;
while (!isdigit(ch)) { f = ch == '-' ? -1 : 1, ch = getchar(); }
while (isdigit(ch)) { x = x * 10 + ch - 48, ch = getchar(); }
x *= f;
}
template <typename T> void print(T x){
if (x < 0) { putchar('-'), x = -x; }
if (x > 9) { print( x / 10); }
putchar(x % 10 + '0');
}
template <typename T,typename... Args> inline void read(T &t,Args&... args) {
read(t);read(args...);
}

const int N = 5009, M = 2e5 + 9;;
int n, m, f[N], ans, cnt;
struct EDGE{
int u, v, w;
}edge[M];
bool cmod(EDGE a, EDGE b) {
return a.w < b.w;
}
int find(int x) {
if (f[x] == x) return x;
return f[x] = find(f[x]);
}

signed main() {
read(n, m);
for (register int i = 1; i <= m; ++i) {
read(edge[i].u, edge[i].v, edge[i].w);
}
sort(edge + 1, edge + 1 + m, cmod);
for (register int i = 1; i <= n; ++i) f[i] = i;
for (register int i = 1, u = 0, v = 0, w = 0; i <= m; ++i) {
u = edge[i].u, v = edge[i].v, w = edge[i].w;
if (find(u) == find(v)) continue;
++cnt;
ans += w;
f[find(u)] = find(v);
}
if (cnt != n - 1) puts("orz");
else print(ans);
return 0;
}