Day 1 (2022.5.14)
// AcWing 785. 快速排序
#include <iostream>
using namespace std;
const int N = 100010;
int q[N];
void quick_sort(int q[], int l, int r)
{
if (l >= r) return;
int i = l - 1, j = r + 1, x = q[(l + r) >> 1];
while (i < j)
{
do i++; while (q[i] < x);
do j--; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j);
quick_sort(q, j+1, r);
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d", &q[i]);
quick_sort(q, 0, n - 1);
for (int i = 0; i < n; i++) printf("%d ", q[i]);
return 0;
}
Day 2 (2022.5.15)
// AcWing 787. 归并排序
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N], tmp[N];
void merge_sort(int q[], int l, int r)
{
if (l>=r) return;
int mid = (l+r)/2;
merge_sort(q, l, mid);
merge_sort(q, mid+1, r);
int k = 0, i = l, j = mid+1;
while (i <= mid && j <= r)
if (q[i] <= q[j]) tmp[k++] = q[i++];
else tmp[k++] = q[j++];
while (i <= mid) tmp[k++] = q[i++];
while (j <= r) tmp[k++] = q[j++];
for (i = l, j = 0; i <= r; i++, j++) q[i] = tmp[j];
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d", &a[i]);
merge_sort(a, 0, n-1);
for (int i = 0; i < n; i++) printf("%d ", a[i]);
return 0;
}
Day 3 (2022.5.16)
// AcWing 788. 逆序对的数量
#include <iostream>
using namespace std;
typedef long long LL;
LL cnt;
const int N = 1e5 + 10;
int a[N], tmp[N];
void merge_sort(int q[], int l, int r)
{
if (l>=r) return;
int mid = (l+r)/2;
merge_sort(q, l, mid);
merge_sort(q, mid+1, r);
int k = 0, i = l, j = mid+1;
while (i<=mid && j<=r)
if (q[i] <= q[j]) tmp[k++] = q[i++];
else
{
tmp[k++] = q[j++];
cnt += mid - i + 1;
}
while (i<=mid) tmp[k++] = q[i++];
while (j<=r) tmp[k++] = q[j++];
for (k=0; l<=r; l++, k++) q[l] = tmp[k];
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d", &a[i]);
merge_sort(a, 0, n-1);
printf("%lld", cnt);
return 0;
}
// AcWing 789. 数的范围
#include <iostream>
using namespace std;
const int N = 100010;
int a[N], n;
void binary_search(int q)
{
int l = 0, r = n-1;
while (l<r)
{
int mid = (l+r)/2;
if (a[mid] >= q) r = mid;
else l = mid + 1;
}
if (a[l] == q) printf("%d ", l);
else
{
printf("-1 -1\n");
return;
}
l = 0, r = n-1;
while (l<r)
{
int mid = (l+r+1) / 2;
if (a[mid] <= q) l = mid;
else r = mid - 1;
}
printf("%d\n", l);
}
int main()
{
int k, q;
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i++) scanf("%d", &a[i]);
while (k--)
{
scanf("%d", &q);
bi_search(q);
}
}
/ AcWing 790. 数的三次方根
#include <iostream>
using namespace std;
int main()
{
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);
return 0;
}
Day 4 (2022.5.17)
// AcWing 791. 高精度加法
#include <iostream>
#include <vector>
using namespace std;
const int N = 1e5 + 10;
vector<int> add(vector<int>& A, vector<int>& B)
{
vector<int> C;
int t = 0;
for (int i = 0; i < A.size() || i < B.size(); i++)
{
if (i < A.size()) t += A[i];
if (i < B.size()) t += B[i];
C.push_back(t % 10);
t /= 10;
}
if (t) C.push_back(1);
return C;
}
int main()
{
vector<int> A, B;
string a, b;
cin >> a >> b;
for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');
auto res = add(A, B);
for (int i = res.size() - 1; i >= 0; i--) printf("%d", res[i]);
return 0;
}
Day 5 (2022.5.18)
C++实现整数除法向上取整 (a + b - 1) / b
// AcWing 792. 高精度减法
#include <iostream>
#include <vector>
using namespace std;
bool cmp(vector<int>& A, vector<int>& B)
{
if (A.size() != B.size()) return A.size() > B.size();
for (int i = A.size() - 1; i >= 0; i--)
{
if (A[i] != B[i]) return A[i] > B[i];
}
return true;
}
vector<int> sub(vector<int>& A, vector<int>& B)
{
vector<int> C;
int t = 0;
for (int i = 0; i < A.size() || i < B.size(); i++)
{
if (i < A.size()) t += A[i];
if (i < B.size()) t -= B[i];
C.push_back((t + 10) % 10);
if (t < 0) t = -1;
else t = 0;
}
if (t) C.push_back(t);
while(C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
int main()
{
string a, b;
vector<int> A, B;
cin >> a >> b;
for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');
vector<int> res;
if (cmp(A, B)) res = sub(A, B);
else
{
res = sub(B, A);
printf("-");
}
for (int i = res.size() - 1; i >= 0; i--) printf("%d", res[i]);
return 0;
}
Day 6 (2022.5.19)
// AcWing 793. 高精度乘法
#include <iostream>
#include <vector>
#include <string>
using namespace std;
const int N = 1e6 + 10;
vector<int> A;
vector<int> multiple(vector<int>& A, int b)
{
vector<int> res;
int t = 0;
for (int i = 0; i < A.size(); i++)
{
t += A[i] * b;
res.push_back(t % 10);
t /= 10;
}
while (t)
{
res.push_back(t % 10);
t /= 10;
}
while (res.size() > 1 && res.back() == 0) res.pop_back();
return res;
}
int main()
{
string s;
int a;
cin >> s >> a;
for (int i = s.size() - 1; i > -1; i--) A.push_back(s[i] - '0');
vector<int> res = multiple(A, a);
for (int i = res.size() - 1; i > -1; i--) printf("%d", res[i]);
return 0;
}
Day 7 (2022.5.22)
// AcWing 794. 高精度除法
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<int> divide(vector<int> A, int& b)
{
vector<int> res;
int t = 0;
for (int i = A.size() - 1; i > -1; i--)
{
t = t * 10 + A[i];
res.push_back(t / b);
t %= b;
}
while (res.size() > 1 && res[0] == 0) res.erase(res.begin());
b = t;
return res;
}
int main()
{
vector<int> A;
int b;
string s_a;
cin >> s_a >> b;
for (int i = s_a.size() - 1; i > -1; i--) A.push_back(s_a[i] - '0');
vector<int> res = divide(A, b);
for (int i = 0; i < res.size(); i++) cout << res[i];
cout << endl << b;
return 0;
}
// AcWing 795. 前缀和
#include <cstdio>
const int N = 100010;
int a[N];
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i < n + 1; i++) scanf("%d", &a[i]);
for (int i = 2; i < n + 1; i++) a[i] += a[i-1];
int l, r;
while (m--)
{
scanf("%d%d", &l, &r);
printf("%d\n", a[r] - a[l-1]);
}
return 0;
}
// AcWing 796. 子矩阵的和
#include <cstdio>
const int N = 1010;
int a[N][N];
int main()
{
int n, m, q;
scanf("%d%d%d", &n, &m, &q);
for (int i = 1; i < n + 1; i++)
for (int j = 1; j < m + 1; j++)
scanf("%d", &a[i][j]);
for (int i = 1; i < n + 1; i++)
{
for (int j = 1; j < m + 1; j++)
{
a[i][j] += a[i-1][j] + a[i][j-1] - a[i-1][j-1];
}
}
int x1, y1, x2, y2;
while (q--)
{
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
printf("%d\n", a[x2][y2] - a[x2][y1-1] - a[x1-1][y2] + a[x1-1][y1-1]);
}
return 0;
}
Day 8 (2022.5.23)
// AcWing 797. 差分
#include <cstdio>
const int N = 100010;
int a[N];
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i < n + 1; i++) scanf("%d", &a[i]);
for (int i = n; i > 1; i--) a[i] -= a[i-1];
int l, r, c;
while (m--)
{
scanf("%d%d%d", &l, &r, &c);
a[l] += c;
a[r+1] -= c;
}
for (int i = 1; i < n + 1; i++)
{
a[i] += a[i-1];
printf("%d ", a[i]);
}
return 0;
}
// AcWing 798. 差分矩阵
// 用插入的方法构造初始二维差分数组
#include <cstdio>
const int N = 1010;
int a[N][N], q[N][N];
void insert(int x1, int y1, int x2, int y2, int c)
{
q[x1][y1] += c;
q[x2+1][y1] -= c;
q[x1][y2+1] -= c;
q[x2+1][y2+1] += c;
}
int main()
{
int n, m, t;
scanf("%d%d%d", &n, &m, &t);
for (int i = 1; i < n + 1; i++)
for (int j = 1; j < m + 1; j++)
scanf("%d", &a[i][j]);
for (int i = 1; i < n + 1; i++)
for (int j = 1; j < m + 1; j++)
insert(i, j, i, j, a[i][j]);
int x1, y1, x2, y2, c;
while (t--)
{
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &c);
insert(x1, y1, x2, y2, c);
}
for (int i = 1; i < n + 1; i++)
{
for (int j = 1; j < m + 1; j++)
{
q[i][j] += q[i-1][j] + q[i][j-1] - q[i-1][j-1];
printf("%d ", q[i][j]);
}
printf("\n");
}
return 0;
}
// AcWing 799. 最长连续不重复子序列
#include <cstdio>
#include <algorithm>
const int N = 100010;
int a[N], q[N];
int main()
{
int n, m_max = 0;
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d", &a[i]);
int i = 0, j = 0;
while (j < n)
{
q[a[j]] += 1;
while (q[a[j]] != 1)
{
q[a[i]] -= 1;
i++;
}
m_max = std::max(m_max, j - i + 1);
j++;
}
printf("%d", m_max);
return 0;
}
Day 9 (2022.5.24)
// AcWing 800. 数组元素的目标和
#include <iostream>
const int N = 1e5 + 10;
int a[N], b[N];
int main()
{
int n, m, x;
scanf("%d%d%d", &n, &m, &x);
for (int i = 0; i < n; i++) scanf("%d", &a[i]);
for (int i = 0; i < m; i++) scanf("%d", &b[i]);
int i = 0, j = m - 1, t;
while (t = a[i] + b[j], t != x)
{
if (j > 0 && t > x) j--;
else i++;
}
printf("%d %d\n", i, j);
return 0;
}
// AcWing 2816. 判断子序列
#include <cstdio>
const int N = 1e5 + 10;
int a[N], b[N];
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) scanf("%d", &a[i]);
for (int i = 0; i < m; i++) scanf("%d", &b[i]);
int i = 0, j = 0;
while (i < n && j < m)
{
if (a[i] == b[j]) i++, j++;
else j++;
}
if (i == n) printf("Yes");
else printf("No");
return 0;
}
// AcWing 801. 二进制中1的个数
#include <cstdio>
int main()
{
int n, cnt = 0, x;
scanf("%d", &n);
while (n--)
{
scanf("%d", &x);
for (; x; x -= x & -x) cnt++;
printf("%d ", cnt);
cnt = 0;
}
return 0;
}
// AcWing 802. 区间和
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 3e5 + 10;
int a[N];
vector<int> alls;
vector<PII> add, query;
int find(int x)
{
int l = 0, r = alls.size() - 1;
while (l < r)
{
int mid = (l + r) / 2;
if (alls[mid] >= x) r = mid;
else l = mid + 1;
}
return l + 1;
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
int x, c;
for (int i = 0; i < n; i++)
{
scanf("%d%d", &x, &c);
add.push_back({x, c});
alls.push_back(x);
}
int l, r;
for (int i = 0; i < m; i++)
{
scanf("%d%d", &l, &r);
query.push_back({l, r});
alls.push_back(l);
alls.push_back(r);
}
sort(alls.begin(), alls.end());
alls.erase(unique(alls.begin(), alls.end()), alls.end());
for (auto item : add)
{
int x = find(item.first);
a[x] += item.second;
}
for (int i = 1; i < alls.size() + 1; i++) a[i] += a[i-1];
for (auto item : query)
{
int l = find(item.first), r = find(item.second);
printf("%d\n", a[r] - a[l-1]);
}
return 0;
}
Day 10 (2022.5.25)
// AcWing 803. 区间合并
#include <cstdio>
#include <vector>
#include <limits.h>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
vector<PII> a;
int main()
{
int n;
scanf("%d", &n);
int l, r;
while (n--)
{
scanf("%d%d", &l, &r);
a.push_back({l, r});
}
sort(a.begin(), a.end());
int cnt = 0, r = INT_MIN;
for (auto item : a)
{
if (item.second > r)
{
if (r < item.first) cnt++;
min = item.second;
}
}
printf("%d", cnt);
return 0;
}
Day 11 (2022.5.26)
// AcWing 826.单链表
#include <iostream>
const int N = 100010;
int head = -1, e[N], ne[N], idx = 0;
void add_to_head(int x)
{
e[idx] = x, ne[idx] = head, head = idx++;
}
void remove(int k)
{
ne[k] = ne[ne[k]];
}
void add(int k, int x)
{
e[idx] = x, ne[idx] = ne[k], ne[k] = idx++;
}
int main()
{
int n;
scanf("%d\n", &n);
int k, x;
char op;
while (n--)
{
scanf("%c", &op);
if (op == 'H')
{
scanf("%d\n", &x);
add_to_head(x);
}
else if (op == 'D')
{
scanf("%d\n", &k);
if (!k) head = ne[head];
else remove(k - 1);
}
else
{
scanf("%d%d\n", &k, &x);
add(k - 1, x);
}
}
while (head != -1)
{
printf("%d ", e[head]);
head = ne[head];
}
return 0;
}
Day 12 (2022.5.27)
// AcWing 827.双链表
#include <iostream>
#include <string>
using namespace std;
const int N = 100010;
int l[N], r[N], e[N], idx = 2;
// 从左到右,从下到上
void insert(int k, int x)
{
e[idx] = x, l[idx] = k, r[idx] = r[k], l[r[k]] = idx, r[k] = idx++;
}
void remove(int k)
{
l[r[k]] = l[k], r[l[k]] = r[k];
}
int main()
{
int n;
scanf("%d", &n);
l[1] = 0, r[0] = 1;
string op;
int k, x;
while (n--)
{
cin >> op;
if (op == "L")
{
cin >> x;
insert(0, x);
}
else if (op == "R")
{
cin >> x;
insert(l[1], x);
}
else if (op == "D")
{
cin >> k;
remove(k + 1);
}
else if (op == "IL")
{
cin >> k >> x;
insert(l[k + 1], x);
}
else
{
cin >> k >> x;
insert(k + 1, x);
}
}
for (int i = r[0]; i != 1; i = r[i]) cout << e[i] << " ";
return 0;
}
Day 13 (2022.5.28)
// AcWing 828. 模拟栈
#include <stack>
#include <iostream>
#include <string>
using namespace std;
int main()
{
stack<int> st;
int n;
cin >> n;
string op;
int x;
while (n--)
{
cin >> op;
if (op == "push")
{
cin >> x;
st.push(x);
}
else if (op == "query")
{
cout << st.top() << endl;
}
else if (op == "pop")
{
st.pop();
}
else
{
if (st.empty()) cout << "YES" << endl;
else cout << "NO" << endl;
}
}
return 0;
}
// yxc 的方法
#include <iostream>
using namespace std;
const int N = 100010;
int m;
int stk[N], tt;
int main()
{
cin >> m;
while (m -- )
{
string op;
int x;
cin >> op;
if (op == "push")
{
cin >> x;
stk[ ++ tt] = x;
}
else if (op == "pop") tt -- ;
else if (op == "empty") cout << (tt ? "NO" : "YES") << endl;
else cout << stk[tt] << endl;
}
return 0;
}
Day 14 (2022.5.29)
// AcWing 3302. 表达式求值
#include <iostream>
#include <unordered_map>
#include <stack>
#include <algorithm>
using namespace std;
stack<int> num;
stack<int> op;
void eval()
{
int b = num.top(); num.pop();
int a = num.top(); num.pop();
char c = op.top(); op.pop();
int x;
if (c == '+') x = a + b;
else if (c == '-') x = a - b;
else if (c == '*') x = a * b;
else x = a / b;
num.push(x);
}
int main()
{
unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
string str;
cin >> str;
for (int i = 0; i < str.size(); i++)
{
char c = str[i];
if (isdigit(c))
{
int x = 0, j = i;
while (j < str.size() && isdigit(str[j]))
x = x * 10 + str[j++] - '0';
i = j - 1;
num.push(x);
}
else if (c == '(') op.push(c);
else if (c == ')')
{
while (op.top() != '(') eval();
op.pop();
}
else
{
while (op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) eval();
op.push(c);
}
}
while (op.size()) eval();
cout << num.top() << endl;
return 0;
}
Day 15 (2022.6.6)
// AcWing 829. 模拟队列
#include <iostream>
#include <string>
using namespace std;
const int N = 100010;
int a[N], head = 1, tail = 0;
int main()
{
int n, x;
string str;
cin >> n;
while (n--)
{
cin >> str;
if (str == "push")
{
cin >> x;
a[++tail] = x;
}
else if (str == "empty")
{
if (tail != head - 1) cout << "NO" << endl;
else cout << "YES" << endl;
}
else if (str == "pop")
{
head++;
}
else
{
cout << a[head] << endl;
}
}
return 0;
}
Day 16 (2022.6.7)
// AcWing 830. 单调栈
#include <iostream>
#include <stack>
using namespace std;
const int N = 100010;
int a[N];
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++) scanf("%d", &a[i]);
stack<int> stk;
for (int i = 0; i < n; i++)
{
while (!stk.empty())
{
if (stk.top() < a[i])
{
printf("%d ", stk.top());
break;
}
else stk.pop();
}
if (stk.empty()) printf("-1 ");
stk.push(a[i]);
}
return 0;
}
// AcWing 154. 滑动窗口
#include <iostream>
#include <deque>
using namespace std;
const int N = 1e6 + 10;
int a[N];
deque<int> q;
int main()
{
int n, k;
cin >> n >> k;
for (int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
if (i > k - 1 && q.front() < i - k + 1) q.pop_front();
while (!q.empty())
{
if (a[q.back()] >= a[i]) q.pop_back();
else break;
}
q.push_back(i);
if (i >= k - 1) printf("%d ", a[q.front()]);
}
printf("\n"); q.clear();
for (int i = 0; i < n; i++)
{
if (i > k - 1 && q.front() < i - k + 1) q.pop_front();
while (!q.empty())
{
if (a[q.back()] <= a[i]) q.pop_back();
else break;
}
q.push_back(i);
if (i >= k - 1) printf("%d ", a[q.front()]);
}
return 0;
}
Day 17 (2022.6.18)
// AcWing 831. KMP字符串
#include <iostream>
using namespace std;
const int N = 100010, M = 1000010;
char s[M], p[N];
int n, m, ne[N];
int main()
{
cin >> n >> p+1 >> m >> s+1;
for (int i = 2, j = 0; i <= n; i++)
{
while (j && p[i] != p[j+1]) j = ne[j];
if (p[i] == p[j+1]) j++;
ne[i] = j;
}
for (int i = 1, j = 0; i <= m; i++)
{
while (j && s[i] != p[j+1]) j = ne[j];
if (s[i] == p[j+1]) j++;
if (j == n)
{
printf("%d ", i - n);
j = ne[j];
}
}
return 0;
}
Day 18 (2022.6.27)
// AcWing 835. Trie字符串统计
#include <iostream>
#include <string>
#include <map>
using namespace std;
map<string, int> m;
int main()
{
int n;
char op;
string s;
cin >> n;
while (n--)
{
cin >> op >> s;
if (op == 'I') m[s] = m[s] + 1;
else cout << m[s] << endl;
}
return 0;
}
// ********************************************************* //
#include <iostream>
#include <string>
using namespace std;
const int N = 1e5 + 1;
int son[N][26], cnt[N], idx = 1;
void insert(string& s)
{
int p = 0;
for (int i = 0; i < s.size(); i++)
{
int u = s[i] - 'a';
if (!son[p][u]) son[p][u] = idx++;
p = son[p][u];
}
cnt[p] += 1;
}
int query(string& s)
{
int p = 0;
for (int i = 0; i < s.size(); i++)
{
int u = s[i] - 'a';
if (!son[p][u]) return 0;
p = son[p][u];
}
return cnt[p];
}
int main()
{
int n;
char op;
string s;
cin >> n;
while (n--)
{
cin >> op >> s;
if (op == 'I') insert(s);
else cout << query(s) << endl;
}
return 0;
}
// *************************************************** //
#include <iostream>
using namespace std;
const int N = 100001;
int son[N][26], cnt[N], idx = 1;
char op[2], s[N];
void insert(char* s)
{
int p = 0;
for (int i = 0; s[i]; i++)
{
int u = s[i] - 'a';
if (!son[p][u]) son[p][u] = idx++;
p = son[p][u];
}
cnt[p] ++;
}
int query(char* s)
{
int p = 0;
for (int i = 0; s[i]; i++)
{
int u = s[i] - 'a';
if (!son[p][u]) return 0;
p = son[p][u];
}
return cnt[p];
}
int main()
{
int n;
scanf("%d", &n);
while (n--)
{
scanf("%s%s", op, s);
if (*op == 'I') insert(s);
else printf("%d\n", query(s));
}
return 0;
}
Day 19 (2022.6.28)
#include <iostream>
using namespace std;
const int N = 1e5, M = 3e6;
int arr[N], son[M][2], idx = 0;
void insert(int x)
{
int p = 0;
for (int i = 30; i >= 0; i--)
{
int u = (x>>i) & 1;
if (!son[p][u]) son[p][u] = ++idx;
p = son[p][u];
}
}
int query(int x)
{
int res = 0, p = 0;
for (int i = 30; i >= 0; i--)
{
int u = (x>>i) & 1;
if (son[p][1-u])
{
res = res + (1<<i);
p = son[p][1-u];
}
else
{
p = son[p][u];
}
}
return res;
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
insert(arr[i]);
}
int res = 0;
for (int i = 0; i < n; i++)
{
res = max(res, query(arr[i]));
}
printf("%d\n", res);
}
Day 20 (2022.6.29)
// AcWing 836. 合并集合
#include <iostream>
using namespace std;
const int N = 100010;
int n, m, p[N];
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
scanf("%d%d",&n,&m);
for (int i = 1; i <= n; i++) p[i] = i;
char c[2];
int a, b;
while (m--)
{
scanf("%s%d%d", &c, &a, &b);
if (*c == 'M') p[find(a)] = find(b);
else
{
if (find(a) == find(b)) printf("%s\n", "Yes");
else printf("%s\n", "No");
}
}
return 0;
}
Day 21 (2022.7.2)
#include <iostream>
#include <string>
using namespace std;
const int N = 100010;
int p[N], cnt[N];
int find(int x)
{
if (x != p[x]) p[x] = find(p[x]);
return p[x];
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
{
p[i] = i, cnt[i] = 1;
}
char op[3];
int a, b;
while (m--)
{
scanf("%s", op);
if (string(op) == "C")
{
scanf("%d%d", &a, &b);
if (find(a) != find(b))
{
cnt[find(b)] = cnt[find(a)] + cnt[find(b)];
p[find(a)] = find(b);
}
}
else if (string(op) == "Q1")
{
scanf("%d%d", &a, &b);
if (find(a) == find(b)) puts("Yes");
else puts("No");
}
else
{
scanf("%d", &a);
printf("%d\n", cnt[find(a)]);
}
}
return 0;
}
Day 22 (2022.7.5)
#include <iostream>
using namespace std;
int const N = 500010;
int p[N], d[N], res;
int find(int x)
{
if (p[x] != x)
{
int t = find(p[x]);
d[x] += d[p[x]];
p[x] = t;
}
return p[x];
}
int main()
{
int n, k;
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) p[i] = i;
int op, x, y;
while (k--)
{
scanf("%d%d%d", &op, &x, &y);
int px, py;
px = find(x), py = find(y);
if (x > n || y > n) res += 1;
else if(op == 1)
{
if (px == py && (d[x] - d[y]) % 3) res += 1;
else if(px != py)
{
p[px] = py;
d[px] = d[y] - d[x];
}
}
else
{
if (px == py && (d[x] - d[y] - 1) % 3) res += 1;
else if(px != py)
{
p[px] = py;
d[px] = d[y] - d[x] + 1;
}
}
}
printf("%d", res);
return 0;
}
Day 23 (2022.7.6)
#include <iostream>
using namespace std;
const int N = 100010;
int h[N], n, m;
void down(int k)
{
int u = k;
if (2*k <= n && h[u]>h[2*k]) u = 2*k;
if (2*k+1 <= n && h[u]>h[2*k+1]) u = 2*k+1;
if (u != k)
{
swap(h[k], h[u]);
down(u);
}
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) scanf("%d", &h[i]);
for (int i = n/2; i > 0; i--) down(i);
while (m--)
{
printf("%d ", h[1]);
h[1] = h[n--];
down(1);
}
return 0;
}
Day 24 (2022.7.11)
// AcWing 839. 模拟堆
// 也可也 #include <cstring>, 用!strcmp(op, "I")
#include <iostream>
using namespace std;
const int N = 100010;
int h[N], hp[N], ph[N], index = 0, len = 0;
void swap_heap(int i, int j)
{
swap(ph[hp[i]], ph[hp[j]]);
swap(hp[i], hp[j]);
swap(h[i], h[j]);
}
void down(int k)
{
int u = k;
if (2 * k <= len && h[2 * k] < h[u]) u = 2 * k;
if (2 * k + 1 <= len && h[2 * k + 1] < h[u]) u = 2 * k + 1;
if (u != k)
{
swap_heap(u, k);
down(u);
}
}
void up(int k)
{
while (k / 2 && h[k / 2]>h[k])
{
swap_heap(k / 2, k);
k /= 2;
}
}
int main()
{
int n, x, y;
scanf("%d", &n);
char op[4];
while (n--)
{
scanf("%s", op);
if (string(op) == "I")
{
scanf("%d", &x);
len++, index++;
ph[index] = len, hp[len] = index;
h[len] = x;
up(len);
}
else if (string(op) == "PM")
{
printf("%d\n", h[1]);
}
else if (string(op) == "DM")
{
swap_heap(1, len--);
down(1);
}
else if (string(op) == "D")
{
scanf("%d", &x);
x = ph[x];
swap_heap(x, len--);
up(x);
down(x);
}
else
{
scanf("%d%d", &x, &y);
x = ph[x];
h[x] = y;
up(x);
down(x);
}
}
std::cin.get();
return 0;
}
Day 25 (2022.7.13)
// AcWing 840. 模拟散列表
// 拉链法
#include <iostream>
#include <cstring>
const int N = 100003;
int h[N], e[N], ne[N], idx = 0;
void insert(int x)
{
int k = (x%N + N) % N;
e[idx] = x, ne[idx] = h[k], h[k] = idx++;
}
void query(int x)
{
int k = (x%N + N) % N;
int index = h[k];
while (index != -1)
{
if (e[index] == x)
{
puts("Yes");
return;
}
index = ne[index];
}
puts("No");
}
int main()
{
memset(h, 0xff, sizeof h);
int n;
scanf("%d", &n);
char op[3];
int x;
while (n--)
{
scanf("%s", op);
scanf("%d", &x);
if (!strcmp(op, "I")) insert(x);
else query(x);
}
return 0;
}
// 开放寻址法
#include <iostream>
#include <cstring>
const int N = 200003, null = 0x3f3f3f3f;
int h[N];
int find(int x)
{
int k = (x%N + N) % N;
while (h[k] != null && h[k]!=x)
{
if (++k == N) k = 0;
}
return k;
}
int main()
{
memset(h, 0x3f, sizeof h);
int n;
scanf("%d", &n);
char op[3];
int x;
while (n--)
{
scanf("%s%d", op, &x);
// 这里由于I,Q只有一个字符,也可以用*op == 'I'
if (!strcmp(op, "I")) h[find(x)] = x;
else
{
if (h[find(x)] == null) puts("No");
else puts("Yes");
}
}
return 0;
}
Day 26 (2022.7.20)
AcWing 841. 字符串哈希
#include <iostream>
using namespace std;
const int N = 100010, P = 131;
unsigned long long h[N], p[N];
char str[N];
int get(int l, int r)
{
return (h[r] - h[l - 1] * p[r - l + 1]) ;
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
scanf("%s", str + 1);
p[0] = 1;
for (int i = 1; i <= n; i++)
{
h[i] = (h[i - 1] * P + str[i]);
p[i] = (p[i - 1] * P);
}
while (m -- )
{
int l1, r1, l2, r2;
scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
if (get(l1, r1) == get(l2, r2)) puts("Yes");
else puts("No");
}
return 0;
}
Day 27 (2022.7.23)
// AcWing 842. 排列数字
#include <iostream>
using namespace std;
int n, st[7], path[7];
void dfs(int k)
{
if (k == n)
{
for (int i = 0; i < n; i++) printf("%d ", path[i]);
printf("\n");
}
for (int i = 1; i <= n; i++)
{
if (!st[i])
{
path[k] = i;
st[i] = 1;
dfs(k+1);
st[i] = 0;
}
}
}
int main()
{
scanf("%d", &n);
dfs(0);
return 0;
}
Day 28 (2022.7.24)
// AcWing 843. n-皇后问题
#include <iostream>
using namespace std;
const int N = 10;
int n, col[N], dg[2*N], bdg[2*N];
char grid[N][N];
void dfs(int r)
{
if (r == n)
{
for (int i = 0; i < n; i++)
puts(grid[i]);
puts("");
return;
}
for (int c = 0; c < n; c++)
{
if (!col[c] && !dg[n + r - c] && !bdg[r + c])
{
col[c] = 1, dg[n + r - c] = 1, bdg[r + c] = 1;
grid[r][c] = 'Q';
dfs(r + 1);
grid[r][c] = '.';
col[c] = 0, dg[n + r - c] = 0, bdg[r + c] = 0;
}
}
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
for (int c = 0; c < n; c++)
{
grid[i][c] = '.';
}
}
dfs(0);
return 0;
}
// AcWing 844. 走迷宫
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 101;
int grid[N][N], d[N][N], n, m;
void bfs()
{
queue<PII> q;
memset(d, 0xff, sizeof d);
d[0][0] = 0;
q.push({0, 0});
int dx[4] = { -1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
while (q.size())
{
PII 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 && grid[x][y] ==0 && d[x][y]==-1)
{
d[x][y] = d[t.first][t.second] + 1;
q.push({x, y});
if (x == n-1 && y == m-1)
{
printf("%d", d[n-1][m-1]);
break;
}
}
}
}
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
scanf("%d", &grid[i][j]);
bfs();
return 0;
}
// AcWing 845. 八数码
#include <string>
#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <queue>
using namespace std;
int bfs(string state)
{
string end = "12345678x";
int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
queue<string> q;
unordered_map<string, int> d;
q.push(state);
d[state] = 0;
while (q.size())
{
string t = q.front();
q.pop();
if (t == end) return d[t];
int dist = d[t], k = t.find('x');
int x = k/3, y = k%3;
for (int i = 0; i < 4; i++)
{
int nx = x + dx[i], ny = y + dy[i];
if (nx>=0 && nx<3 && ny>=0 && ny<3)
{
swap(t[nx*3 + ny], t[k]);
if (!d.count(t))
{
d[t] = dist + 1;
q.push(t);
}
swap(t[nx*3 + ny], t[k]);
}
}
}
return -1;
}
int main()
{
char c;
string state;
for (int i = 0; i < 9; i++)
{
cin >> c;
state += c;
}
cout << bfs(state) << endl;
return 0;
}
Day 29 (2022.7.26)
AcWing 846. 树的重心
#include <iostream>
#include <cstring>
using namespace std;
const int N = 100010;
int h[N], e[2*N], ne[2*N], st[N], idx = 0, ans = N, n;
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int dfs(int u)
{
st[u] = 1;
int sum = 1, res = 0;
int i = h[u];
while (i != -1)
{
int j = e[i];
if (!st[j])
{
int s = dfs(j);
res = max(res, s);
sum += s;
}
i = ne[i];
}
res = max(res, n - sum);
ans = min(ans, res);
return sum;
}
int main()
{
memset(h, -1, sizeof h);
scanf("%d", &n);
int a, b;
for (int i = 0; i < n-1; i++)
{
scanf("%d%d", &a, &b);
add(a, b);
add(b, a);
}
dfs(1);
printf("%d", ans);
}
Day 30 (2022.7.27)
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int N = 100010;
int h[N], e[N], ne[N], idx = 0, n, m, dist[N];
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int bfs()
{
queue<int> q;
q.push(1);
dist[1] = 0;
while (q.size())
{
int t = q.front();
q.pop();
int i = h[t];
while ( i!=-1 )
{
int b = e[i];
if (dist[b] == -1)
{
q.push(b);
dist[b] = dist[t] + 1;
}
i = ne[i];
}
}
return dist[n];
}
int main()
{
memset(h, -1, sizeof h);
memset(dist, -1, sizeof dist);
scanf("%d%d", &n, &m);
int a, b;
for (int i = 0; i < m; i++)
{
scanf("%d%d", &a, &b);
add(a, b);
}
cout << bfs() << endl;
return 0;
}
······