Back to School '24 P1 - Kicking
按照題意模擬即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;
int n, m, k;
char c;
vector<int> sum[2][N];
vector<int> a[N];
signed main() {
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m + 1; j++) {
sum[0][i].push_back(0);
sum[1][i].push_back(0);
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> c;
a[i].push_back(c);
sum[0][i][j] = sum[0][i][j - 1] + (c == 'A');
sum[1][i][j] = sum[1][i][j - 1] + (c == 'B');
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (a[i][j - 1] == '.') {
cout << ".";
}
else if (a[i][j - 1] == 'A') {
if (sum[1][i][min(j + k, m)] - sum[1][i][j - 1] > 0) {
cout << "N";
}
else cout << "Y";
}
else {
if (sum[0][i][j] - sum[0][i][max(0ll, j - k - 1)] > 0) {
cout << "N";
}
else cout << "Y";
}
}
cout << "\n";
}
return 0;
}
Back to School '24 P2 - Cheating
注意到一個重要的性質,就是 \(a_i\) 為遞增序列,那麼我們會發現,他改的區間一定是上一個區間後面的,模擬即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5;
int n, m, a[N], b[N], ans[N];
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= n; i++) {
cin >> b[i];
}
int last = 1;
for (int i = 1; i <= n; i++) {
if (last + b[i] - 1 <= m) {
ans[last] += a[i];
ans[last + b[i]] -= a[i];
last += b[i];
if (last == m + 1) {
last = 1;
}
}
else {
ans[last] += a[i];
ans[m + 1] -= a[i];
b[i] -= (m - last + 1);
ans[1] += a[i];
ans[min(b[i] + 1, last)] -= a[i];
last = min(b[i] + 1, last);
}
}
for (int i = 1; i <= m; i++) {
ans[i] += ans[i - 1];
}
for (int i = 1; i <= m; i++) {
cout << ans[i] << " ";
}
return 0;
}
Back to School '24 P3 - Tournament
我們可以發現,他合併答案是簡直和線段樹一摸一樣,所以直接線段樹維護即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = (1 << 18) + 5;
struct node {
int maxi, ans;
void clean() {
maxi = ans = 0;
}
}tr[N * 4];
int n, p, a[N];
bool vis[N];
void build(int i, int l, int r) {
if (l == r) {
if (l == 1) {
tr[i].maxi = p, tr[i].ans = 0;
}
else tr[i].maxi = a[l - 1], tr[i].ans = 0;
return ;
}
int mid = (l + r) >> 1;
build(i * 2, l, mid);
build(i * 2 + 1, mid + 1, r);
tr[i].ans = tr[i * 2].ans + tr[i * 2 + 1].ans + (tr[i * 2].maxi - tr[i * 2 + 1].maxi) * (tr[i * 2].maxi - tr[i * 2 + 1].maxi);
tr[i].maxi = max(tr[i * 2].maxi, tr[i * 2 + 1].maxi);
}
void modify(int i, int l, int r, int p, int x) {
if (l == r) {
tr[i].maxi = x;
tr[i].ans = 0;
return ;
}
int mid = (l + r) >> 1;
if (mid >= p) modify(i * 2, l, mid, p, x);
else modify(i * 2 + 1, mid + 1, r, p, x);
tr[i].ans = tr[i * 2].ans + tr[i * 2 + 1].ans + (tr[i * 2].maxi - tr[i * 2 + 1].maxi) * (tr[i * 2].maxi - tr[i * 2 + 1].maxi);
tr[i].maxi = max(tr[i * 2].maxi, tr[i * 2 + 1].maxi);
}
signed main() {
cin >> n;
for (int i = 1; i < n; i++) {
cin >> a[i];
vis[a[i]] = true;
}
for (int i = 1; i <= n; i++) {
if (!vis[i]) {
p = i;
}
}
build(1, 1, n);
for (int i = 1; i <= n; i++) {
cout << tr[1].ans << " ";
if (i < n) {
modify(1, 1, n, i, a[i]);
modify(1, 1, n, i + 1, p);
}
}
return 0;
}
Back to School '24 P4 - Candidates
我們假如考慮每一種因素,他一定要滿足在每個區間內是遞增的,用 \(set\) 維護,做一個類似於拓撲排序的即可
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int n, k, a[N], cnt[N];
vector<int> r[N], v[N], ans;
bool vis[N];
priority_queue<int, vector<int>, greater<int> > q;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
r[i].push_back(0);
}
for (int i = 1; i <= n; i++) {
for (int j = 1, c; j <= k; j++) {
cin >> c;
r[i].push_back(c);
}
}
for (int j = 1; j <= k; j++) {
for (int i = 1; i < n; i++) {
if (r[a[i]][j] < r[a[i + 1]][j]) {
cnt[j]++;
vis[i] = true;
v[i].push_back(j);
}
}
}
for (int i = 1; i <= k; i++) {
if (!cnt[i]) {
q.push(i);
}
}
while (!q.empty()) {
int cur = q.top();
q.pop();
ans.push_back(cur);
vector<int> tmp;
for (int i = 1; i < n; i++) {
if (r[a[i]][cur] > r[a[i + 1]][cur] && vis[i]) {
tmp.push_back(i);
}
}
for (auto cur : tmp) {
for (auto u : v[cur]) {
cnt[u]--;
if (!cnt[u]) {
q.push(u);
}
}
vis[cur] = false;
v[cur].clear();
}
}
for (int i = 1; i <= k; i++) {
if (cnt[i]) {
cout << "-1";
return 0;
}
}
for (auto cur : ans) {
cout << cur << " ";
}
return 0;
}