Jordan's Castles
我们先思考如何快速求出 \(b_1, b_2, b_3...b_n\) 显然我们可以直接用二分找到,然后我们可以直接将 \(a_i\) 改为 \(min(a[i], b[i])\),然后统计答案即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;
int t, n, a[N];
void Solve() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
int ans = 0;
for (int i = n; i >= 1; i--) {
int l = 0, r = n;
while (l < r) {
int mid = (l + r + 1) >> 1;
if (a[mid] >= i) {
l = mid;
}
else r = mid - 1;
}
ans += max(0ll, a[i] - l);
a[i] = min(a[i], l);
}
cout << ans << "\n";
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> t;
while (t--) {
Solve();
}
return 0;
}
Game on a Graph
我们看到一个重要的性质 "移除该分量中编号最小的顶点",那么我们可以从大到小枚举编号,每次枚举出边 \(v\) 那么只要 \(v < i\) 就可以直接用并查集合并,最后判断一下奇偶性即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;
int t, n, m, fa[N], f[N], sz[N];
vector<int> g[N], new_g[N];
void dfs(int u) {
sz[u] = 1;
for (auto v : new_g[u]) {
dfs(v);
sz[u] += sz[v];
}
}
int find(int x) {
if (fa[x] == x) {
return x;
}
return fa[x] = find(fa[x]);
}
void Solve() {
cin >> n >> m;
for (int i = 0; i <= n; i++) {
fa[i] = i;
g[i].clear();
new_g[i].clear();
}
for (int i = 1, u, v; i <= m; i++) {
cin >> u >> v;
u++, v++;
g[u].push_back(v);
g[v].push_back(u);
}
for (int i = n; i >= 1; i--) {
for (auto v : g[i]) {
if (v > i && find(v) != i) {
f[find(v)] = i;
new_g[i].push_back(find(v));
fa[find(v)] = i;
}
}
}
for (int i = 1; i <= n; i++) {
if (find(i) == i) {
f[i] = 0;
new_g[0].push_back(i);
}
}
dfs(0);
for (int i = 1; i <= n; i++) {
if (f[i] == 0 || (n - sz[f[i]]) % 2 == 1) {
cout << i - 1 << ' ';
}
}
cout << "\n";
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> t;
while (t--) {
Solve();
}
return 0;
}
标签:return,int,20240911,mid,long,fa,find
From: https://www.cnblogs.com/libohan/p/18473003