Skip to content

Commit 0dc2de3

Browse files
committed
Petrozavodsk Winter 2023. Day 4: KAIST+KOI Contest, Grand Prix of Korea
1 parent 9206968 commit 0dc2de3

3 files changed

Lines changed: 355 additions & 0 deletions

File tree

QOJ/14021.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* @file 14021.cpp
3+
* @author Macesuted (i@macesuted.moe)
4+
* @date 2025-08-24
5+
*
6+
* @copyright Copyright (c) 2025
7+
*
8+
*/
9+
10+
#include <bits/stdc++.h>
11+
using namespace std;
12+
13+
#define endl '\n'
14+
15+
#define maxn 4005
16+
17+
vector<vector<int>> graph;
18+
bool up[maxn];
19+
20+
void dfs(int p) {
21+
up[p] = true;
22+
for (auto q : graph[p]) {
23+
dfs(q);
24+
if (up[q]) up[p] = false;
25+
}
26+
return;
27+
}
28+
29+
void solve(void) {
30+
int n;
31+
cin >> n;
32+
33+
graph.clear(), graph.resize(n + 1);
34+
for (int i = 2, fa; i <= n; i++) cin >> fa, graph[fa].push_back(i);
35+
36+
dfs(1);
37+
38+
cout << "Yes" << endl;
39+
cout << n - 1 << endl;
40+
for (int i = 2; i <= n; i++) {
41+
int x = 1, y = i;
42+
if (up[i]) swap(x, y);
43+
cout << x << ' ' << y << endl;
44+
}
45+
46+
return;
47+
}
48+
49+
int main() {
50+
ios::sync_with_stdio(false), cin.tie(nullptr);
51+
52+
int _ = 1;
53+
cin >> _;
54+
while (_--) solve();
55+
56+
return 0;
57+
}

QOJ/6104.cpp

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/**
2+
* @file 6104.cpp
3+
* @author Macesuted (i@macesuted.moe)
4+
* @date 2025-09-05
5+
*
6+
* @copyright Copyright (c) 2025
7+
*
8+
*/
9+
10+
#include <bits/stdc++.h>
11+
using namespace std;
12+
13+
#ifndef LOCAL
14+
#define endl '\n'
15+
#endif
16+
17+
bool mem1;
18+
19+
#define maxn 100005
20+
#define maxk 12
21+
22+
using pii = pair<int, int>;
23+
24+
class SegmentTree {
25+
private:
26+
int a[maxn << 2], cnt[maxn << 2];
27+
int n;
28+
29+
void pushUp(int p) {
30+
a[p] = min(a[p << 1], cnt[p << 1] + a[p << 1 | 1]);
31+
cnt[p] = cnt[p << 1] + cnt[p << 1 | 1];
32+
return;
33+
}
34+
35+
void build(int p, int l, int r) {
36+
if (l == r) return cnt[p] = 0, a[p] = 1e9, void();
37+
int mid = (l + r) >> 1;
38+
build(p << 1, l, mid), build(p << 1 | 1, mid + 1, r);
39+
return pushUp(p);
40+
}
41+
void insert(int p, int l, int r, int qp, int v) {
42+
if (l == r) return a[p] = v, cnt[p]++, void();
43+
int mid = (l + r) >> 1;
44+
qp <= mid ? insert(p << 1, l, mid, qp, v) : insert(p << 1 | 1, mid + 1, r, qp, v);
45+
return pushUp(p);
46+
}
47+
int query(int p, int l, int r, int qp, int rv = 1e9) {
48+
if (l == r) return rv;
49+
int mid = (l + r) >> 1;
50+
return qp <= mid ? query(p << 1, l, mid, qp, min(rv + cnt[p << 1 | 1], a[p << 1 | 1]))
51+
: query(p << 1 | 1, mid + 1, r, qp, rv);
52+
}
53+
54+
public:
55+
void resize(int _n) { return n = _n, void(); }
56+
void build(void) { return build(1, 1, n); }
57+
void insert(int p, int v) { return insert(1, 1, n, p, v); }
58+
int query(int p) { return query(1, 1, n, p); }
59+
} SGT[maxk];
60+
61+
class FenwickTree {
62+
private:
63+
int a[maxn];
64+
65+
public:
66+
void add(int p, int v) {
67+
for (int i = p; i < maxn; i += i & -i) a[i] += v;
68+
return;
69+
}
70+
int sum(int p) {
71+
int ans = 0;
72+
for (int i = p; i; i -= i & -i) ans += a[i];
73+
return ans;
74+
}
75+
} FT;
76+
77+
pii a[maxn];
78+
79+
void solve(void) {
80+
int n, L, K;
81+
cin >> n >> L >> K;
82+
for (int i = 1; i <= n; i++) cin >> a[i].first, a[i].second = -i;
83+
84+
if (K == 1) {
85+
int ans = 0;
86+
for (int i = 1; i < L; i++) ans += a[i].first >= a[L].first;
87+
for (int i = L + 1; i <= n; i++) ans += a[i].first > a[L].first;
88+
return cout << ans << endl, void();
89+
}
90+
91+
for (int t = 1; t < K; t++) SGT[t].resize(n), SGT[t].build();
92+
93+
sort(a + 1, a + n + 1, greater<pii>());
94+
95+
for (int i = 1; i <= n; i++) {
96+
int p = -a[i].second;
97+
98+
if (p == L) {
99+
int ans = SGT[K - 1].query(L) + FT.sum(p);
100+
if (ans >= 1e9) return cout << -1 << endl, void();
101+
return cout << ans << endl, void();
102+
}
103+
104+
for (int t = K - 2; t; t--) SGT[t + 1].insert(p, SGT[t].query(p));
105+
106+
FT.add(p, +1);
107+
SGT[1].insert(p, i - FT.sum(p));
108+
}
109+
110+
return;
111+
}
112+
113+
bool mem2;
114+
115+
int main() {
116+
ios::sync_with_stdio(false), cin.tie(nullptr);
117+
#ifdef LOCAL
118+
cerr << "Memory Cost: " << abs(&mem1 - &mem2) / 1024. / 1024. << "MB" << endl;
119+
#endif
120+
121+
int _ = 1;
122+
while (_--) solve();
123+
124+
#ifdef LOCAL
125+
cerr << "Time Cost: " << clock() * 1000. / CLOCKS_PER_SEC << "MS" << endl;
126+
#endif
127+
return 0;
128+
}

QOJ/6106.cpp

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/**
2+
* @file 6106.cpp
3+
* @author Macesuted (i@macesuted.moe)
4+
* @date 2025-09-05
5+
*
6+
* @copyright Copyright (c) 2025
7+
*
8+
*/
9+
10+
#include <bits/stdc++.h>
11+
using namespace std;
12+
13+
#ifndef LOCAL
14+
#define endl '\n'
15+
#endif
16+
17+
bool mem1;
18+
19+
#define maxn 100005
20+
21+
class SegmentTree {
22+
private:
23+
array<int, 10> a[maxn << 2];
24+
int n;
25+
26+
array<int, 10> merge(const array<int, 10>& x, const array<int, 10>& y) {
27+
array<int, 10> ans = x;
28+
for (int i = 0; i < 10; i++) ans[i] += y[i];
29+
return ans;
30+
}
31+
32+
void build(int p, int l, int r, const string& s) {
33+
if (l == r) {
34+
x[l] = s[l - 1] - '0';
35+
for (int t = 0; t < 10; t++) a[p][t] = (x[l] == t);
36+
return;
37+
}
38+
int mid = (l + r) >> 1;
39+
build(p << 1, l, mid, s), build(p << 1 | 1, mid + 1, r, s);
40+
return a[p] = merge(a[p << 1], a[p << 1 | 1]), void();
41+
}
42+
void update(int p, int l, int r, int qp, int v) {
43+
if (l == r) return a[p][x[l]]--, a[p][x[l] = v]++, void();
44+
int mid = (l + r) >> 1;
45+
qp <= mid ? update(p << 1, l, mid, qp, v) : update(p << 1 | 1, mid + 1, r, qp, v);
46+
return a[p] = merge(a[p << 1], a[p << 1 | 1]), void();
47+
}
48+
array<int, 10> getPre(int p, int l, int r, int qp) {
49+
if (r <= qp) return a[p];
50+
int mid = (l + r) >> 1;
51+
if (qp <= mid) return getPre(p << 1, l, mid, qp);
52+
return merge(a[p << 1], getPre(p << 1 | 1, mid + 1, r, qp));
53+
}
54+
int getNext(int p, int l, int r, int qp) {
55+
if (a[p][x[qp]] == r - l + 1) return n + 1;
56+
if (l == r) return l;
57+
int mid = (l + r) >> 1;
58+
if (qp <= mid) {
59+
int ans = getNext(p << 1, l, mid, qp);
60+
if (ans != n + 1) return ans;
61+
}
62+
return getNext(p << 1 | 1, mid + 1, r, qp);
63+
}
64+
65+
public:
66+
int x[maxn];
67+
68+
void build(const string& s) { return build(1, 1, n = s.size(), s); }
69+
void update(int p, int v) { return update(1, 1, n, p, v); }
70+
array<int, 10> getPre(int p) { return getPre(1, 1, n, p); }
71+
int getNext(int p) { return getNext(1, 1, n, p); }
72+
} SGT;
73+
74+
array<int, 10> cnt;
75+
76+
void solve(void) {
77+
string X, Y;
78+
cin >> X >> Y;
79+
80+
int n = X.size();
81+
for (int i = 0; i < 10; i++) cnt[i] = 0;
82+
for (int i = 0; i < n; i++) cnt[X[i] - '0']++;
83+
SGT.build(Y);
84+
85+
auto chk = [&](int p) -> bool {
86+
array<int, 10> cnt = ::cnt;
87+
if (p) {
88+
array<int, 10> pre = SGT.getPre(p);
89+
for (int i = 0; i < 10; i++)
90+
if ((cnt[i] -= pre[i]) < 0) return false;
91+
}
92+
93+
for (int t = 9, i = p + 1; t >= 0; t--) {
94+
if (!cnt[t]) continue;
95+
if (t != SGT.x[i]) return t > SGT.x[i];
96+
int len = SGT.getNext(i) - i, rlen = min(len, cnt[t]);
97+
len -= rlen, i += rlen;
98+
cnt[t] -= rlen;
99+
if (cnt[t]) return t > SGT.x[i];
100+
}
101+
return true;
102+
};
103+
104+
int q;
105+
cin >> q;
106+
while (q--) {
107+
int op, i;
108+
cin >> op >> i;
109+
if (op == 1) {
110+
int x;
111+
cin >> x;
112+
SGT.update(i, x);
113+
} else {
114+
if (!chk(0)) {
115+
cout << -1 << endl;
116+
continue;
117+
}
118+
119+
int l = 0, r = n + 1;
120+
while (l + 1 < r) {
121+
int mid = (l + r) >> 1;
122+
(chk(mid) ? l : r) = mid;
123+
}
124+
125+
if (i <= l) {
126+
cout << SGT.x[i] << endl;
127+
continue;
128+
}
129+
130+
array<int, 10> cnt = ::cnt;
131+
if (l) {
132+
array<int, 10> pre = SGT.getPre(l);
133+
for (int i = 0; i < 10; i++) cnt[i] -= pre[i];
134+
}
135+
136+
int d = SGT.x[r] + 1;
137+
while (!cnt[d]) d++;
138+
if (i == r) {
139+
cout << d << endl;
140+
continue;
141+
}
142+
cnt[d]--;
143+
144+
for (int t = 0, p = r; t <= 9; p += cnt[t++])
145+
if (i <= p + cnt[t]) {
146+
cout << t << endl;
147+
break;
148+
}
149+
}
150+
}
151+
152+
return;
153+
}
154+
155+
bool mem2;
156+
157+
int main() {
158+
ios::sync_with_stdio(false), cin.tie(nullptr);
159+
#ifdef LOCAL
160+
cerr << "Memory Cost: " << abs(&mem1 - &mem2) / 1024. / 1024. << "MB" << endl;
161+
#endif
162+
163+
int _ = 1;
164+
while (_--) solve();
165+
166+
#ifdef LOCAL
167+
cerr << "Time Cost: " << clock() * 1000. / CLOCKS_PER_SEC << "MS" << endl;
168+
#endif
169+
return 0;
170+
}

0 commit comments

Comments
 (0)