并查集
#include <bits/stdc++.h>
using namespace std;
//#define int long long
#define VI vector<int>
typedef long long ll;
typedef pair<int,int> PII;
#define debug(x, y) cout << '#' << x << '+' << y << endl
const int N = 1e4 + 10;
int p[N];
int find(int x) // 查询根节点
{
if (x != p[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;
while(m -- )
{
int op, x, y;
cin >> op >> x >> y;
if (op == 1)
{
int a = find(x), b = find(y);
p[a] = b;
}
else {
int a = find(x), b = find(y);
cout << (a == b ? "Y" : "N") << endl;
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
T = 1;
//cin >> T;
while(T -- )
{
solve();
}
return 0;
}
拓展
#include <bits/stdc++.h>
using namespace std;
//#define int long long
#define VI vector<int>
typedef long long ll;
typedef pair<int,int> PII;
#define debug(x, y) cout << '#' << x << '+' << y << endl
const int N = 1010;
int p[2 * 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 <= 2 * n; i ++)
p[i] = i;
while(m -- )
{
string op;
int a, b;
cin >> op >> a >> b;
if (op == "E")
{
p[find(a + n)] = find(b);
p[find(b + n)] = find(a);
// 将 a+n 、b+n 合并到 b、a
}
else {
p[find(a)] = find(b);
}
}
int res = 0;
for (int i = 1; i <= n; i ++)
res += (p[i] == i ? 1 : 0);
cout << res;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
T = 1;
//cin >> T;
while(T -- )
{
solve();
}
return 0;
}
并查集判二分图
#include <bits/stdc++.h>
using namespace std;
//#define int long long
#define VI vector<int>
typedef long long ll;
typedef pair<int,int> PII;
#define debug(x, y) cout << '#' << x << '+' << y << endl
const int N = 1010;
int t = 1;
int p[2 * N];
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
void solve()
{
cout << "case " << t ++ << ":\n";
int n, m;
cin >> n >> m;
for (int i = 1; i <= 2 * n; i ++)
p[i] = i;
for (int i = 1; i <= m; i ++)
{
int a, b;
cin >> a >> b;
p[find(a + n)] = p[find(b)];
p[find(b + n)] = p[find(a)];
}
for (int i= 1; i <= n; i ++)
{
if (p[find(i + n)] == p[find(i)])
{
cout << "No\n";
return;
}
}
cout << "Yes\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
T = 1;
cin >> T;
while(T -- )
{
solve();
}
return 0;
}
单调栈
#include <bits/stdc++.h>
using namespace std;
//#define int long long
#define VI vector<int>
typedef long long ll;
typedef pair<int,int> PII;
#define debug(x, y) cout << '#' << x << '+' << y << endl
const int N = 3e6 + 10;
int a[N];
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i ++)
cin >> a[i];
stack<int> st, res;
for (int i = n; i >= 1; i --)
{
while(st.size() && a[st.top()] <= a[i])
st.pop();
if (st.empty()) res.push(0);
// 右边没有比它大的
else res.push(st.top());
st.push(i);
}
while(res.size())
{
cout << res.top() << ' ';
res.pop();
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
T = 1;
//cin >> T;
while(T -- )
{
solve();
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
//#define int long long
#define VI vector<int>
typedef long long ll;
typedef pair<int,int> PII;
#define debug(x, y) cout << '#' << x << '+' << y << endl
const int N = 1010;
int f[N][N];
void solve()
{
string s[N];
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i ++)
{
cin >> s[i];
s[i] = "#" + s[i];
}
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
if (s[i][j] == 'Q')
{
f[i][j] = f[i - 1][j] + 1;
}
else f[i][j] = 0;
stack<PII> st;
int res = 0;
for (int i = 1; i <= n; i ++){
for (int j = 1; j <= m; j ++)
{
int len = 0;
while(st.size() && st.top().first >= f[i][j])
{
res = max(res, st.top().first * (st.top().second + len));
len += st.top().second;
st.pop();
}
st.push({f[i][j], len + 1});
}
int len = 0;
while(st.size())
{
res = max(res, st.top().first * (st.top().second + len));
len += st.top().second;
st.pop();
}
}
cout << res;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
T = 1;
//cin >> T;
while(T -- )
{
solve();
}
return 0;
}
单调队列
双端队列 deque
deque<int> q; // 定义
q.push_front(x); // 将x插入到队列头
q.push_back(x); // 将x插入到队列尾
q.pop_front(); // 删除队头元素
q.pop_back(); // 删除队尾元素
#include <bits/stdc++.h>
using namespace std;
//#define int long long
#define VI vector<int>
typedef long long ll;
typedef pair<int,int> PII;
#define debug(x, y) cout << '#' << x << '+' << y << endl
const int N = 1e6 + 10;
int a[N];
void solve()
{
deque<int> q;
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; i ++)
cin >> a[i];
for (int i = 1; i <= n; i ++) // 构造递增
{
while(q.size() && q.front() <= i - k)
q.pop_front();
while(q.size() && a[q.back()] >= a[i])
q.pop_back();
q.push_back(i);
if (i >= k) cout << a[q.front()] << ' ';
}
cout << '\n';
q.clear();
for (int i = 1; i <= n; i ++)
{
while(q.size() && q.front() <= i - k) // 构造递减
q.pop_front();
while(q.size() && a[q.back()] <= a[i])
q.pop_back();
q.push_back(i);
if (i >= k) cout << a[q.front()] << ' ';
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
T = 1;
//cin >> T;
while(T -- )
{
solve();
}
return 0;
}