C. LCS
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
const int N = 1005;
int f[N][N];
int lcs(string &a, string &b, int n) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
f[i][j] = max(f[i][j - 1], f[i - 1][j]);
if (a[i - 1] == b[j - 1]) {
f[i][j] = max(f[i][j], f[i - 1][j - 1] + 1);
}
}
}
return f[n][n];
}
void push(string &s, char ch, int time) {
for (int i = 0; i < time; i++) {
s.push_back(ch);
}
}
void solve() {
int a, b, c, n;
scanf("%d %d %d %d", &a, &b, &c, &n);
int arr[3] = {a, b, c};
sort(arr, arr + 3, std::greater<int>());
int x = arr[0], y = arr[1], z = arr[2];
if (x + y - z > n) {
puts("NO");
return;
}
string s1, s2, s3;
push(s1, 'a', x);
push(s1, 'x', n - s1.size());
push(s2, 'a', x);
push(s2, 'b', y - z);
push(s2, 'y', n - s2.size());
push(s3, 'a', z);
push(s3, 'b', y - z);
push(s3, 'z', n - s3.size());
string *ss[] = {&s1, &s2, &s3};
int per[] = {0, 1, 2};
do {
string &ss1 = *ss[per[0]], &ss2 = *ss[per[1]], &ss3 = *ss[per[2]];
if (lcs(ss1, ss2, n) == a && lcs(ss2, ss3, n) == b && lcs(ss1, ss3, n) == c) {
printf("%s\n%s\n%s\n", ss1.c_str(), ss2.c_str(), ss3.c_str());
}
} while (next_permutation(per, per + 3));
}
int main() {
solve();
return 0;
}
F. Just a joke
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 1003;
int father[N], vis[N];
int Find(int x) {
return father[x] == x ? x : father[x] = Find(father[x]);
}
void Union(int u, int v) {
u = Find(u), v = Find(v);
if (u != v) father[u] = v;
}
void solve() {
for (int i = 0; i < N; i++) {
father[i] = i;
}
int n, m;
scanf("%d %d", &n, &m);
int cnt = 0;
for (int i = 0; i < m; i++) {
int u, v;
scanf("%d %d", &u, &v);
if (Find(u) != Find(v)) Union(u, v);
else cnt++;
}
for (int i = 1; i <= n; i++) {
int t = Find(i);
if (!vis[t]) {
vis[t] = true;
cnt++;
}
}
if (cnt & 1) puts("Alice");
else puts("Bob");
}
int main() {
solve();
return 0;
}
I. Inverse Pair
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 200005;
int a[N], vis[N], tmp[N];
long long ans = 0;
void mergeSort(int *a, int l, int r) {
if (l == r) return;
int mid = l + r >> 1;
mergeSort(a, l, mid);
mergeSort(a, mid + 1, r);
int i = l, j = mid + 1;
int tot = 0;
while (i <= mid && j <= r) {
if (a[j] < a[i]) {
tmp[tot++] = a[j++];
ans = ans + mid - i + 1;
} else {
tmp[tot++] = a[i++];
}
}
while (i <= mid) tmp[tot++] = a[i++];
while (j <= r) tmp[tot++] = a[j++];
for (i = 0, j = l; i < tot; i++, j++) {
a[j] = tmp[i];
}
}
void solve() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
for (int i = 0; i < n; i++) {
if (!vis[a[i] + 1]) {
vis[a[i]] = true;
} else {
vis[++a[i]] = true;
}
}
mergeSort(a, 0, n - 1);
cout << ans << endl;
}
int main() {
solve();
return 0;
}
J. Average
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 100005;
int a[N];
double pre[N];
bool check(int n, int x, double ave) {
for (int i = 1; i <= n; i++) {
pre[i] = pre[i - 1] + a[i] - ave;
}
double minn = 0;
for (int i = x; i <= n; i++) {
minn = min(minn, pre[i - x]);
if (pre[i] - minn >= 0) return true;
}
return false;
}
double work(int n, int x) {
double l = 1e6, r = -1e6;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
l = min(l, (double)a[i]);
r = max(r, (double)a[i]);
}
while (r - l > 1e-8) {
double mid = (l + r) / 2;
if (check(n, x, mid)) l = mid;
else r = mid;
}
return l;
}
void solve() {
int n, m, x, y;
scanf("%d %d %d %d", &n, &m, &x, &y);
double aa = work(n, x);
double bb = work(m, y);
printf("%.8lf\n", aa + bb);
}
int main() {
solve();
return 0;
}