目录
零
初始化1:
#include <bits/stdc++.h>
#define ioscc ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl '\n'
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int MAX = (1ll << 31) - 1;
const int MIN = 1 << 31;
const int N = 1e5 + 10;
int main()
{
ioscc;
return 0;
}
初始化2:
#include <bits/stdc++.h>
#define ioscc ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl '\n'
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int MAX = (1ll << 31) - 1;
const int MIN = 1 << 31;
const int N = 1e5 + 10;
void solve()
{
}
int main()
{
ioscc;
int T;
cin >> T;
while(T--)
solve();
return 0;
}
一、基础算法
1.前缀和:
一维:
void solve()
{
int n;
int s[N];
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> s[i];
s[i] += s[i - 1];
}
for (int i = 1; i <= n; i++)
{
cout << s[i] << ' ';
}
cout << endl;
}
二维:
void solve()
{
int n, m, q;
int s[N][N];
cin >> n >> m >> q;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> s[i][j];
s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
}
}
while (q--)
{
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
printf("%d\n", s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]);
}
}
2.差分:
一维:
void solve()
{
int n, m;
int a[N], b[N];
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
b[i] = a[i] - a[i - 1];
int l, r, v;
while (m--)
{
cin >> l >> r >> v;
b[l] += v, b[r + 1] -= v;
}
for (int i = 1; i <= n; i++)
b[i] += b[i - 1];
for (int i = 1; i <= n; i++)
cout << b[i] << ' ';
cout << endl;
}
二维:
int n, m, q;
int a[N][N], b[N][N];
void insert(int x1, int y1, int x2, int y2, int v)
{
b[x1][y1] += v;
b[x2 + 1][y1] -= v;
b[x1][y2 + 1] -= v;
b[x2 + 1][y2 + 1] += v;
}
void solve()
{
cin >> n >> m >> q;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
insert(i, j, i, j, a[i][j]);
while (q--)
{
int x1, y1, x2, y2, v;
cin >> x1 >> y1 >> x2 >> y2 >> v;
insert(x1, y1, x2, y2, v);
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
cout << b[i][j] << ' ';
cout << endl;
}
}
3.二分:
整数:
void solve()
{
// 前驱
int l = 0, r = 1e9;
while (l < r)
{
int mid = l + r + 1 >> 1;
if (check(mid))
l = mid;
else
r = mid - 1;
}
cout << l << endl;
// 后继
int l = 0, r = 1e9;
while (l < r)
{
int mid = l + r >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
cout << l << endl;
}
实数:
寻找数的三次方根
void solve()
{
double x;
cin >> x;
double l = -100, r = 100;
while (r - l > 1e-8)
{
double mid = (l + r) / 2;
if (mid * mid * mid >= x)
r = mid;
else
l = mid;
}
printf("%.6lf\n", l);
}
4.位运算
lowbit:
int lowbit(int x)
{
return x & -x;
}
5.RMQ
二、数据结构
1.并查集:
只维护集合:
int p[N];
int find(int x)
{
if (p[x] != x)
p[x] = find(p[x]);
return p[x];
}
void solve()
{
int n, m;
cin >> n >> m;
// 初始化
for (int i = 1; i <= n; i++)
p[i] = i;
/*
操作1:将a和b放到一个集合中
操作2:判断a和b是否在一个集合中
*/
while (m--)
{
int op;
int a, b;
cin >> op >> a >> b;
if (op == 1)
{
a = find(a), b = find(b);
p[a] = b;
}
else
{
a = find(a), b = find(b);
if (a == b)
puts("Yes");
else
puts("No");
}
}
}
维护集合中点的数量:
int p[N];
int s[N];
int find(int x)
{
if (p[x] != x)
p[x] = find(p[x]);
return p[x];
}
void solve()
{
int n, m;
cin >> n >> m;
// 初始化
for (int i = 1; i <= n; i++)
p[i] = i, s[i] = 1;
/*
操作1:将a和b放到一个集合中
操作2:判断a和b是否在一个集合中
操作3:输出连通块中点的数量
*/
while (m--)
{
int op;
int a, b;
cin >> op;
if (op == 1)
{
cin >> a >> b;
a = find(a), b = find(b);
if (a != b)
{
s[b] += s[a];
p[a] = b;
}
}
else if (op == 2)
{
cin >> a >> b;
a = find(a), b = find(b);
if (a == b)
puts("Yes");
else
puts("No");
}
else
{
cin >> a;
a = find(a);
cout << s[a] << endl;
}
}
}
2.哈希表:
数字哈希 - 开放寻址法:
int h[N];
int find(int x)
{
int t = (x % N + N) % N;
while (h[t] != INF && h[t] != x)
{
t++;
if (t == N)
t = 0;
}
return t;
}
void solve()
{
memset(h, 0x7f, sizeof h);
int n;
cin >> n;
while (n--)
{
int op;
int x;
cin >> op >> x;
/*
操作1:将数字映射到哈希表中
操作2:判断哈希表中有没有值
*/
if (op == 1)
h[find(x)] = x;
else
{
if (h[find(x)] == INF)
cout << "NO" << endl;
else
cout << "YES" << endl;
}
}
}
3.栈
4.队列
5.单调栈
6.单调队列
7.链表
8.KMP
9.Trie
10.数组数组:
11.线段树:
三、搜索
1.DFS:
全排列
int n, path[N];
bool st[N];
void dfs(int u)
{
if (u == n)
{
for (int i = 0; i < n; i++)
cout << path[i] << ' ';
cout << endl;
}
for (int i = 1; i <= n; i++)
{
if (!st[i])
{
path[u] = i;
st[i] = 1;
dfs(u + 1);
st[i] = 0;
}
}
}
void solve()
{
cin >> n;
dfs(0);
}
2.BFS:
走迷宫
int n, m;
int g[N][N], d[N][N];
int bfs()
{
queue<pii> q;
memset(d, -1, sizeof d);
d[0][0] = 0;
q.push({0, 0});
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
while (q.size())
{
auto t = q.front();
q.pop();
for (int i = 0; i < 4; i++)
{
int x = t.first + dx[i], y = t.second + dy[i];
if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1)
{
d[x][y] = d[t.first][t.second] + 1;
q.push({x, y});
}
}
}
return d[n - 1][m - 1];
}
void solve()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> g[i][j];
}
}
cout << bfs() << endl;
}