Skip to content

Commit ae6fc30

Browse files
misc
1 parent 736c51d commit ae6fc30

File tree

6 files changed

+498
-0
lines changed

6 files changed

+498
-0
lines changed

APIO/APIO 07-Backup.cpp

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* https://github.com/dolphingarlic/CompetitiveProgramming/blob/master/APIO/APIO%2007-backup.cpp
3+
*/
4+
#include <bits/stdc++.h>
5+
6+
using namespace std;
7+
8+
using ll = long long;
9+
#define ii pair<int, int>
10+
#define f first
11+
#define s second
12+
#define pb push_back
13+
#define mp make_pair
14+
#define all(x) x.begin(), x.end()
15+
#define sz(x) (int)x.size()
16+
#define F0R(i, n) for (int i = 0; i < n; i++)
17+
#define FOR(i, a, b) for (int i = a; i < b; i++)
18+
#define inf 1000000010
19+
20+
void solve() {
21+
int n, k; cin >> n >> k;
22+
vector<int> A(n); F0R(i, n) cin >> A[i];
23+
vector<ll> dist(n-1);
24+
vector<int> L(n), R(n);
25+
priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;
26+
F0R(i, n-1) {
27+
dist[i] = A[i+1]-A[i];
28+
pq.push(mp(dist[i], i));
29+
L[i] = i-1; R[i] = i+1;
30+
}
31+
vector<bool> alive(n, 1);
32+
ll best = 0;
33+
int ct = 0;
34+
while (!pq.empty()) {
35+
pair<ll, int> u = pq.top(); pq.pop();
36+
if (!alive[u.s]) continue;
37+
best += u.f;
38+
ct++;
39+
if (ct == k) break;
40+
if (L[u.s] >= 0 && R[u.s] < n-1) {
41+
int l = L[u.s], r = R[u.s];
42+
L[u.s] = L[l], R[u.s] = R[r];
43+
if (L[u.s] >= 0) R[L[u.s]] = u.s;
44+
if (R[u.s] < n-1) L[R[u.s]] = u.s;
45+
if (alive[l] && alive[r]) {
46+
dist[u.s] = dist[r] + dist[l] - dist[u.s];
47+
pq.push(mp(dist[u.s], u.s));
48+
} else {
49+
alive[u.s] = 0;
50+
}
51+
alive[l] = alive[r] = 0;
52+
} else {
53+
if (L[u.s] >= 0) alive[L[u.s]] = 0;
54+
if (R[u.s] < n-1) alive[R[u.s]] = 0;
55+
alive[u.s] = 0;
56+
}
57+
}
58+
cout << best << "\n";
59+
}
60+
61+
int main() {
62+
cin.tie(0)->sync_with_stdio(0);
63+
64+
int t; cin >> t;
65+
while (t--) {
66+
solve();
67+
}
68+
69+
return 0;
70+
}

APIO/APIO 16-gap.cpp

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include <bits/stdc++.h>
2+
#include "gap.h"
3+
4+
using namespace std;
5+
6+
#define f first
7+
#define s second
8+
#define ll long long
9+
#define ii pair<ll, ll>
10+
11+
ii get(ll a, ll b) {
12+
b = min(b, (ll)1e18);
13+
ii x;
14+
MinMax(a, b, &x.f, &x.s);
15+
return x;
16+
}
17+
18+
long long findGap(int T, int N)
19+
{
20+
if (T == 1) {
21+
vector<ll> nums, nums2;
22+
ii range = make_pair(1, (ll)1e18);
23+
for (int i = 0; i < (N+1)/2; i++) {
24+
if (range.f > range.s) break;
25+
ii res = get(range.f, range.s);
26+
if (res.f == -1) break;
27+
nums.push_back(res.f); nums2.push_back(res.s);
28+
range = make_pair(res.f+1, res.s-1);
29+
}
30+
reverse(nums2.begin(), nums2.end());
31+
for (ll x : nums2) nums.push_back(x);
32+
ll best = 0;
33+
for (int i = 0; i < (int)nums.size() - 1; i++) {
34+
best = max(best, nums[i+1] - nums[i]);
35+
}
36+
return best;
37+
}
38+
39+
40+
ii boundary = get(1, 1e18);
41+
ll block = (boundary.s-boundary.f)/(N-1);
42+
ll prev = boundary.f;
43+
44+
ll ans = 0;
45+
for (ll cur = boundary.f + 1; cur < boundary.s; cur += block + 1) {
46+
ii thing = get(cur, cur+block);
47+
if (thing.f == -1) continue;
48+
ans = max(ans, thing.f - prev);
49+
prev = thing.s;
50+
}
51+
52+
ans = max(ans, boundary.s - prev);
53+
54+
return ans;
55+
}

COI/COI 15-cvenk.cpp

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
#include <bits/stdc++.h>
2+
3+
using namespace std;
4+
5+
using ll = long long;
6+
#define ii pair<ll, ll>
7+
#define f first
8+
#define s second
9+
#define pb push_back
10+
#define mp make_pair
11+
#define all(x) x.begin(), x.end()
12+
#define sz(x) (int)x.size()
13+
#define F0R(i, n) for (int i = 0; i < n; i++)
14+
#define FOR(i, a, b) for (int i = a; i < b; i++)
15+
#define inf 1000000010
16+
17+
int n;
18+
vector<ii> A;
19+
20+
int ctr = 1;
21+
struct node {
22+
node *down = nullptr, *right = nullptr;
23+
ll numNodes = 0, distToParent = 0;
24+
int id = 0;
25+
} root;
26+
27+
pair<char, int> getNextMove(ii x, int downDist, int rightDist) {
28+
char dir = 'S';
29+
int loc = 0;
30+
int i = 30;
31+
while (i >= 0) {
32+
char curDir = 'S';
33+
if (x.f & (1 << i)) curDir = 'D';
34+
if (x.s & (1 << i)) curDir = 'R';
35+
if (curDir != 'S') {
36+
if (downDist > 0 || rightDist > 0) {
37+
if (curDir == 'D') {
38+
downDist -= (1 << i);
39+
} else {
40+
rightDist -= (1 << i);
41+
}
42+
//cout << downDist << " "<< rightDist << " " << curDir << " " << i << endl;
43+
assert(downDist >= 0 && rightDist >= 0);
44+
} else {
45+
if (dir == 'S') dir = curDir;
46+
if (dir != curDir) break;
47+
loc += (1 << i);
48+
}
49+
}
50+
i--;
51+
}
52+
return mp(dir, loc);
53+
}
54+
55+
void add(node *n, int downDist, int rightDist, vector<ii> A, bool isMovingDown) {
56+
vector<pair<int, ii>> movingDown, movingRight;
57+
58+
for (auto x : A) {
59+
pair<char, int> c = getNextMove(x, downDist, rightDist);
60+
if (c.f == 'D') {
61+
movingDown.pb(make_pair(c.s+downDist, x));
62+
} else if (c.f == 'R') {
63+
movingRight.pb(make_pair(c.s+rightDist, x));
64+
}
65+
}
66+
sort(all(movingDown)); sort(all(movingRight));
67+
68+
if (isMovingDown) {
69+
int prev = downDist;
70+
for (int i = 0; i < sz(movingDown); i++) {
71+
int iInitial = i;
72+
int nodeCt = 1;
73+
vector<ii> nextSet; nextSet.pb(movingDown[i].s);
74+
while (i+1 < sz(movingDown) && movingDown[i].f == movingDown[i+1].f) {
75+
i++;
76+
nodeCt++;
77+
nextSet.pb(movingDown[i].s);
78+
}
79+
n->down = new node;
80+
n->down->id = ctr++;
81+
n->down->distToParent = movingDown[i].f - prev;
82+
n->down->numNodes = sz(movingDown)-iInitial;
83+
add(n->down, movingDown[i].f, rightDist, nextSet, !isMovingDown);
84+
prev = movingDown[i].f;
85+
n = n->down;
86+
}
87+
} else {
88+
int prev = rightDist;
89+
for (int i = 0; i < sz(movingRight); i++) {
90+
int iInitial = i;
91+
int nodeCt = 1;
92+
vector<ii> nextSet; nextSet.pb(movingRight[i].s);
93+
while (i+1 < sz(movingRight) && movingRight[i].f == movingRight[i+1].f) {
94+
i++;
95+
nodeCt++;
96+
nextSet.pb(movingRight[i].s);
97+
}
98+
n->right = new node;
99+
n->right->id = ctr++;
100+
n->right->distToParent = movingRight[i].f - prev;
101+
n->right->numNodes = sz(movingRight)-iInitial;
102+
add(n->right, downDist, movingRight[i].f, nextSet, !isMovingDown);
103+
prev = movingRight[i].f;
104+
n = n->right;
105+
}
106+
}
107+
}
108+
109+
ll solve(node *x, ll parentCt) {
110+
//cout << x->id << " has " << x->numNodes << " nodes and dist to parent of " << x->distToParent << endl;
111+
ll best = 0;
112+
if (x->down) {
113+
//cout << "moving down from " << x->id << endl;
114+
ll ex = x->numNodes - x->down->numNodes + parentCt;
115+
best = min(best, solve(x->down, ex) + x->down->distToParent*(ex) - x->down->numNodes*x->down->distToParent);
116+
}
117+
if (x->right) {
118+
//cout << "moving right from " << x->id << endl;
119+
ll ex = x->numNodes - x->right->numNodes + parentCt;
120+
best = min(best, solve(x->right, ex) + x->right->distToParent*(ex) - x->right->numNodes*x->right->distToParent);
121+
}
122+
return best;
123+
}
124+
125+
int main() {
126+
cin.tie(0)->sync_with_stdio(0);
127+
128+
cin >> n;
129+
A.resize(n);
130+
F0R(i, n) cin >> A[i].f >> A[i].s;
131+
132+
root.numNodes = n;
133+
add(&root, 0, 0, A, 0);
134+
add(&root, 0, 0, A, 1);
135+
136+
ll base = 0;
137+
for (auto x : A) base += x.f + x.s;
138+
cout << solve(&root, 0) + base << endl;
139+
140+
return 0;
141+
}

NOI/NOI 18-citymapping.cpp

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#include <bits/stdc++.h>
2+
#include "citymapping.h"
3+
using namespace std;
4+
5+
using ll = long long;
6+
#define ii pair<int, int>
7+
#define f first
8+
#define s second
9+
#define mp make_pair
10+
#define pb push_back
11+
#define all(x) x.begin(), x.end()
12+
13+
vector<ii> adj[1010];
14+
ll sz[1010];
15+
ii pa[1010];
16+
vector<pair<int, ii>> edges;
17+
18+
ll dfsSize(int u, int a1, int a2) {
19+
sz[u] = 1;
20+
for (ii v : adj[u]) {
21+
if (v.f == a1 || v.f == a2) continue;
22+
sz[u] += dfsSize(v.f, a1, a2);
23+
}
24+
return sz[u];
25+
}
26+
27+
pair<int, ll> getEndpoint(int u, int a1, int a2) {
28+
int best = -1;
29+
ll bestDist = 0;
30+
for (ii v : adj[u]) {
31+
if (v.f == a1 || v.f == a2) continue;
32+
if (best == -1 || sz[best] < sz[v.f]) {
33+
best = v.f;
34+
bestDist = v.s;
35+
}
36+
}
37+
if (best == -1) return mp(u, 0);
38+
pair<int, ll> ret = getEndpoint(best, a1, a2);
39+
ret.s += bestDist;
40+
return ret;
41+
}
42+
43+
void solve(int root, int avoid, int avoid2, int target, ll rootToTarget) {
44+
dfsSize(root, avoid, avoid2);
45+
pair<int, ll> endpoint = getEndpoint(root, avoid, avoid2);
46+
//cout << root << " " << endpoint.f << endl;
47+
if (endpoint.f == root) {
48+
edges.pb(mp(rootToTarget, mp(root, target)));
49+
adj[root].pb(mp(target, rootToTarget));
50+
pa[target] = mp(root, rootToTarget);
51+
//cout << "attaching " << target << " to " << root << " with weight " << rootToTarget << endl;
52+
} else {
53+
ll d = (rootToTarget + get_distance(endpoint.f, target) - endpoint.s) / 2;
54+
int prevNode = -1;
55+
int node = endpoint.f;
56+
ll nodeDist = endpoint.s;
57+
while (nodeDist > rootToTarget - d) {
58+
assert(pa[node].f != -1);
59+
nodeDist -= pa[node].s;
60+
prevNode = node;
61+
node = pa[node].f;
62+
}
63+
assert(nodeDist == rootToTarget - d);
64+
solve(node, prevNode, avoid, target, d);
65+
}
66+
}
67+
68+
void find_roads(int N, int Q, int A[], int B[], int W[]) {
69+
int root = 1;
70+
pa[1] = mp(-1, -1);
71+
72+
vector<pair<ll, int>> nodes;
73+
for (int i = 2; i <= N; i++) {
74+
nodes.pb(mp(get_distance(root, i), i));
75+
}
76+
sort(all(nodes));
77+
78+
for (pair<ll, int> x : nodes) {
79+
//cout << "sovling for " << x.s << endl;
80+
solve(root, -1, -1, x.s, x.f);
81+
}
82+
83+
for (int i = 0; i < N-1; i++) {
84+
A[i] = edges[i].s.f;
85+
B[i] = edges[i].s.s;
86+
W[i] = edges[i].f;
87+
}
88+
89+
return;
90+
}

0 commit comments

Comments
 (0)