传送门 Codeforces Round #835 (Div. 4)
∗ * ∗E. Binary Inversions
Tutorial
当我们将一个
0
0
0 变为
1
1
1 时,减少的逆序对个数为当前位置前
1
1
1 的个数,增加的逆序对个数为当前位置后
0
0
0 的个数。当我们将一个
1
1
1 变为
0
0
0 时,减少的逆序对个数为当前位置后
0
0
0 的个数,增加的逆序对个数为当前位置前
1
1
1 的个数。
可以肯定的是,将第一个出现的
0
0
0 变为
1
1
1 和将最后一个出现的
1
1
1 变为
0
0
0 所增加的逆序对个数最大。我们可以维护一个数组
b
b
b 表示到当前位置数组中
1
1
1 的个数进行优化。
赛时数据范围开大了并用了全局 memset 而TLE了呜呜呜
Solution
#include <bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define pdd pair<double,double>
#define inf 0x3f3f3f3f
const int N = 1e6 + 7;
using namespace std;
int a[N], b[N];
signed main() {
int t;
cin >> t;
while (t--) {
int n, ans = 0, p1 = 0, p2 = 0;
b[0]=0;
bool f = 1;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
b[i] = b[i - 1] + a[i];
if (a[i] == 0) ans += b[i - 1];
if (f && a[i] == 0) p1 = i, f = 0;
if (a[i] == 1) p2 = i;
}
int res = ans;
if (p1) ans = max(ans, res - b[p1 - 1] + (n - p1 - b[n] + b[p1]));
if (p2) ans = max(ans, res - (n - p2 - b[n] + b[p2]) + b[p2 - 1]);
cout << ans << endl;
}
}
F. Quests
Tutorial
因为我们要尽快挣到c个硬币,所以我们优先选择做给的硬币多的任务。
接着二分答案
k
k
k ,每次做第
i
%
k
i \ \% \ k
i % k 个任务( 这里要确保
i
%
k
<
n
i\ \%\ k < n
i % k<n )
Solution
#include <bits/stdc++.h>
#define int long long
#define pii pair<int, int>
#define inf 0x3f3f3f3f
const int N = 2e5 + 7;
using namespace std;
int a[N];
void solve() {
int n, c, d;
cin >> n >> c >> d;
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a + n, greater<int>());
int l = 0, r = d + 1;
while (l < r) {
int mid = (l + r + 1) >> 1, sum = 0;
for (int i = 0; i < d; i++)
if (i % mid < n) sum += a[i % mid];
if (sum >= c) l = mid;
else r = mid - 1;
}
if (l == d + 1) cout << "Infinity\n";
else if (l == 0) cout << "Impossible\n";
else cout << l - 1 << '\n';
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) solve();
}
G. SlavicG’s Favorite Problem
Tutorial
因为我们不知道从哪里传送到哪里,所以进行两次
d
f
s
dfs
dfs 。
第一次求出从
a
a
a 出发,记录所有能到的点的异或值。
第二次从
b
b
b 出发遍历所有能到的点,当某点
y
y
y 的异或值与从
a
a
a 出发的某点
x
x
x 的异或值相等时,则我们有走法:
a
→
x
→
y
→
b
a \rightarrow x \rightarrow y \rightarrow b
a→x→y→b 满足题意。
Solution
#include <bits/stdc++.h>
#define int long long
#define pii pair<int, int>
#define inf 0x3f3f3f3f
const int N = 2e5 + 7;
using namespace std;
int n, a, b;
int e[N], w[N], ne[N], h[N], idx;
bool f;
set<int> p;
void add(int x, int y, int z) {
e[idx] = y, w[idx] = z, ne[idx] = h[x], h[x] = idx++;
}
void dfs1(int u, int fa, int k) {
p.insert(k);
for (int i = h[u]; i != -1; i = ne[i]) {
int j = e[i];
if (j == b || j == fa) continue;
dfs1(j, u, k ^ w[i]);
}
}
void dfs2(int u, int fa, int k) {
for (int i = h[u]; i != -1; i = ne[i]) {
int j = e[i];
if (j == fa) continue;
dfs2(j, u, k ^ w[i]);
if (f) return;
if (p.count(k ^ w[i])) {
f = 1;
return;
}
}
}
void solve() {
memset(h, -1, sizeof h);
p.clear();
f = idx = 0;
cin >> n >> a >> b;
int u, v, q;
for (int i = 1; i < n; i++) cin >> u >> v >> q, add(u, v, q), add(v, u, q);
dfs1(a, -1, 0);
dfs2(b, -1, 0);
if (f) cout << "YES\n";
else cout << "NO\n";
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) solve();
}