#include "catdog.h"
#include <bits/stdc++.h>
using namespace std;
int n;
const int maxn = 100010;
const int inf = 1000000000;
int subsize[maxn];
int bigch[maxn];
int myspot[maxn];
int mycol[maxn]; //store the current color of this node
vector<int> preorder; //this is the special preorder thing
vector<int> adj[maxn];
int par[maxn];
int chainhead[maxn]; //pretty sure this is all that matters
//don't need tail??
int chainend[maxn];
int ccost[maxn][2]; //cost of being colored 1 or 2
int pardiff[maxn][2];
struct mat {
int v[2][2];
};
const bool debug = false;
mat seg[maxn*4];
void printmat(mat & thing) {
cout << thing.v[0][0] << ", " << thing.v[0][1] << ", " << thing.v[1][0] <<
", " << thing.v[1][1] << endl;
}
mat merge(mat& a, mat& b) {
//no reason to not pass by reference
mat res;
res.v[0][0] = res.v[0][1] = res.v[1][0] = res.v[1][1] = inf;
for (int i = 0; i <= 1; i++) {
for (int j = 0; j <= 1; j++) {
res.v[i][j] = min(res.v[i][j],
a.v[i][0] + b.v[0][j]);
res.v[i][j] = min(res.v[i][j],
a.v[i][0] + 1 + b.v[1][j]);
res.v[i][j] = min(res.v[i][j],
a.v[i][1] + 1 + b.v[0][j]);
res.v[i][j] = min(res.v[i][j],
a.v[i][1] + b.v[1][j]);
}
}
// if (debug) {
// cout << " merge of ";
// printmat(a);
// cout << " and ";
// printmat(b);
// cout << " produces ";
// printmat(res);
// }
return res;
}
void predfs(int u, int p = -1) {
par[u] = p;
if (debug) cout << u << " has parent " << p << endl;
subsize[u] = 1;
for (int v : adj[u]) {
if (v == p) continue;
predfs(v, u);
subsize[u] += subsize[v];
if (subsize[v] > subsize[bigch[u]]) {
bigch[u] = v;
}
}
}
void dfs(int u) {
preorder.push_back(u);
myspot[u] = preorder.size()-1;
if (par[u] != -1 && bigch[par[u]] == u) {
chainhead[u] = chainhead[par[u]];
}
else chainhead[u] = u;
if (debug) cout << "dfs: " << u << " has head " << chainhead[u] << endl;
chainend[chainhead[u]] = u; //now I am the smallest
if (bigch[u]) {
dfs(bigch[u]);
}
for (int v : adj[u]) {
if (v != bigch[u] && v != par[u]) {
dfs(v);
}
}
}
void buildtree(int ss = 1, int se = n, int si = 0) {
//pretty sure this is a useless method
if (ss == se) {
seg[si].v[0][0] = seg[si].v[0][1] = seg[si].v[1][0] = seg[si].v[1][1] = inf;
if (mycol[preorder[ss]] != 1) seg[si].v[1][1] = 0 + ccost[preorder[ss]][1];
if (mycol[preorder[ss]] != 2) seg[si].v[0][0] = 0 + ccost[preorder[ss]][0];
return;
}
int mid = (ss+se)/2;
buildtree(ss, mid, si*2+1);
buildtree(mid+1, se, si*2+2);
seg[si] = merge(seg[si*2+1], seg[si*2+2]);
}
void upd(int spot, int ss = 1, int se = n, int si = 0) {
if (ss == se) {
//update explicitly
seg[si].v[0][0] = seg[si].v[0][1] = seg[si].v[1][0] = seg[si].v[1][1] = inf;
if (mycol[preorder[ss]] != 1) seg[si].v[1][1] = 0 + ccost[preorder[ss]][1];
if (mycol[preorder[ss]] != 2) seg[si].v[0][0] = 0 + ccost[preorder[ss]][0];
if (debug) {
cout << "updating " << spot << endl;
cout << " "; printmat(seg[si]);
}
return;
}
int mid = (ss+se)/2;
if (spot <= mid) upd(spot, ss, mid, si*2+1);
else upd(spot, mid+1, se, si*2+2);
seg[si] = merge(seg[si*2+1], seg[si*2+2]);
}
mat zs; //zeroes
mat query(int qs, int qe, int ss = 1, int se = n, int si = 0) {
if (qs > qe || ss > se || qs > se || qe < ss) return zs;
if (qs <= ss && se <= qe) {
return seg[si];
}
int mid = (ss+se)/2;
if (qs > mid) {
return query(qs, qe, mid+1, se, si*2+2);
}
if (qe <= mid) {
return query(qs, qe, ss, mid, si*2+1);
}
mat lhs = query(qs, qe, ss, mid, si*2+1);
mat rhs = query(qs, qe, mid+1, se, si*2+2);
return merge(lhs, rhs);
}
int uph(int u) {
//update up the HLD structure
// if (debug) cout << "start of an HLD trek: ";
while (true) { //should return eventually
int nx = chainhead[u];
// cout << u << " goes to " << nx << endl;
upd(myspot[u]);
if (debug) {
cout << " " << u << " :: " << ccost[u][0] << " - " << ccost[u][1] << endl;
mat cccc = query(myspot[u], myspot[u]);
cout << " "; printmat(cccc) ;
}
mat cv = query(myspot[nx], myspot[chainend[nx]]);
int c0 = min(cv.v[0][0], cv.v[0][1]);
int c1 = min(cv.v[1][0], cv.v[1][1]);
// if (debug) cout << u << " ";
if (nx == 1) {
// cout << "THING THING: ";
// printmat(cv);
// if (debug) cout << 1 << endl;
if (debug) cout << c0 << " VVVVV " << c1 << endl;
// if (debug) cout << "CCOSTS: " << ccost[1][0] << " -- " << ccost[1][1] << endl;
return min(c0, c1);
}
// if (debug) cout << " at " << u << " with " << c0 << " and " << c1 << endl;
// if (debug) {
// cout << " ";
// printmat(cv);
// }
int op = par[nx];
ccost[op][0] += min(c0, c1 + 1) - min(pardiff[nx][0], pardiff[nx][1] + 1);
ccost[op][1] += min(c1, c0 + 1) - min(pardiff[nx][1], pardiff[nx][0] + 1);
pardiff[nx][0] = c0;
pardiff[nx][1] = c1;
u = op;
}
}
void initialize(int N, vector<int> A, vector<int> B) {
n = N;
for (int i = 0; i < N-1; i++) {
adj[A[i]].push_back(B[i]);
adj[B[i]].push_back(A[i]);
}
par[1] = -1;
preorder.push_back(-1); //just buffer it so I can one-index
predfs(1);
dfs(1); //this is to get the preorder
buildtree(); //do not need this because the answer is
zs.v[0][1] = zs.v[1][0] = inf;
// cout << "DONE WITH INIT" << endl;
}
int cat(int v) {
if (debug) cout << "CAT at " << v << endl;
mycol[v] = 1;
return uph(v);
}
int dog(int v) {
if (debug) cout << "DOG at " << v << endl;
mycol[v] = 2;
if (debug) uph(v);
if (debug) {
for (int i = 1; i <= n; i++) {
cout << i << " ::: ";
mat cc = query(myspot[i], myspot[i]);
printmat(cc);
}
}
return uph(v);
}
int neighbor(int v) {
if (debug) cout << "EMPTY at " << v << endl;
mycol[v] = 0;
return uph(v);
}
//THIS IS DONE IN THE WEIRD IOI STYLE
//MUST BE DONE ONLINE
//let's do the HLD thing where ranges are consecutive in a single segment tree
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
3 ms |
2680 KB |
Output is correct |
2 |
Correct |
3 ms |
2680 KB |
Output is correct |
3 |
Correct |
3 ms |
2680 KB |
Output is correct |
4 |
Correct |
3 ms |
2680 KB |
Output is correct |
5 |
Correct |
4 ms |
2680 KB |
Output is correct |
6 |
Correct |
3 ms |
2808 KB |
Output is correct |
7 |
Correct |
3 ms |
2680 KB |
Output is correct |
8 |
Correct |
3 ms |
2680 KB |
Output is correct |
9 |
Correct |
3 ms |
2680 KB |
Output is correct |
10 |
Correct |
3 ms |
2808 KB |
Output is correct |
11 |
Correct |
3 ms |
2680 KB |
Output is correct |
12 |
Correct |
3 ms |
2680 KB |
Output is correct |
13 |
Correct |
3 ms |
2680 KB |
Output is correct |
14 |
Correct |
3 ms |
2680 KB |
Output is correct |
15 |
Correct |
3 ms |
2764 KB |
Output is correct |
16 |
Correct |
3 ms |
2684 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
3 ms |
2680 KB |
Output is correct |
2 |
Correct |
3 ms |
2680 KB |
Output is correct |
3 |
Correct |
3 ms |
2680 KB |
Output is correct |
4 |
Correct |
3 ms |
2680 KB |
Output is correct |
5 |
Correct |
4 ms |
2680 KB |
Output is correct |
6 |
Correct |
3 ms |
2808 KB |
Output is correct |
7 |
Correct |
3 ms |
2680 KB |
Output is correct |
8 |
Correct |
3 ms |
2680 KB |
Output is correct |
9 |
Correct |
3 ms |
2680 KB |
Output is correct |
10 |
Correct |
3 ms |
2808 KB |
Output is correct |
11 |
Correct |
3 ms |
2680 KB |
Output is correct |
12 |
Correct |
3 ms |
2680 KB |
Output is correct |
13 |
Correct |
3 ms |
2680 KB |
Output is correct |
14 |
Correct |
3 ms |
2680 KB |
Output is correct |
15 |
Correct |
3 ms |
2764 KB |
Output is correct |
16 |
Correct |
3 ms |
2684 KB |
Output is correct |
17 |
Correct |
4 ms |
2808 KB |
Output is correct |
18 |
Correct |
5 ms |
2808 KB |
Output is correct |
19 |
Correct |
5 ms |
2936 KB |
Output is correct |
20 |
Correct |
4 ms |
2808 KB |
Output is correct |
21 |
Correct |
4 ms |
2808 KB |
Output is correct |
22 |
Correct |
4 ms |
2808 KB |
Output is correct |
23 |
Correct |
6 ms |
2808 KB |
Output is correct |
24 |
Correct |
5 ms |
2808 KB |
Output is correct |
25 |
Correct |
5 ms |
2808 KB |
Output is correct |
26 |
Correct |
4 ms |
2808 KB |
Output is correct |
27 |
Correct |
5 ms |
2808 KB |
Output is correct |
28 |
Correct |
4 ms |
2808 KB |
Output is correct |
29 |
Correct |
5 ms |
2936 KB |
Output is correct |
30 |
Correct |
4 ms |
2808 KB |
Output is correct |
31 |
Correct |
4 ms |
2808 KB |
Output is correct |
32 |
Correct |
5 ms |
2808 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
3 ms |
2680 KB |
Output is correct |
2 |
Correct |
3 ms |
2680 KB |
Output is correct |
3 |
Correct |
3 ms |
2680 KB |
Output is correct |
4 |
Correct |
3 ms |
2680 KB |
Output is correct |
5 |
Correct |
4 ms |
2680 KB |
Output is correct |
6 |
Correct |
3 ms |
2808 KB |
Output is correct |
7 |
Correct |
3 ms |
2680 KB |
Output is correct |
8 |
Correct |
3 ms |
2680 KB |
Output is correct |
9 |
Correct |
3 ms |
2680 KB |
Output is correct |
10 |
Correct |
3 ms |
2808 KB |
Output is correct |
11 |
Correct |
3 ms |
2680 KB |
Output is correct |
12 |
Correct |
3 ms |
2680 KB |
Output is correct |
13 |
Correct |
3 ms |
2680 KB |
Output is correct |
14 |
Correct |
3 ms |
2680 KB |
Output is correct |
15 |
Correct |
3 ms |
2764 KB |
Output is correct |
16 |
Correct |
3 ms |
2684 KB |
Output is correct |
17 |
Correct |
4 ms |
2808 KB |
Output is correct |
18 |
Correct |
5 ms |
2808 KB |
Output is correct |
19 |
Correct |
5 ms |
2936 KB |
Output is correct |
20 |
Correct |
4 ms |
2808 KB |
Output is correct |
21 |
Correct |
4 ms |
2808 KB |
Output is correct |
22 |
Correct |
4 ms |
2808 KB |
Output is correct |
23 |
Correct |
6 ms |
2808 KB |
Output is correct |
24 |
Correct |
5 ms |
2808 KB |
Output is correct |
25 |
Correct |
5 ms |
2808 KB |
Output is correct |
26 |
Correct |
4 ms |
2808 KB |
Output is correct |
27 |
Correct |
5 ms |
2808 KB |
Output is correct |
28 |
Correct |
4 ms |
2808 KB |
Output is correct |
29 |
Correct |
5 ms |
2936 KB |
Output is correct |
30 |
Correct |
4 ms |
2808 KB |
Output is correct |
31 |
Correct |
4 ms |
2808 KB |
Output is correct |
32 |
Correct |
5 ms |
2808 KB |
Output is correct |
33 |
Correct |
313 ms |
11580 KB |
Output is correct |
34 |
Correct |
123 ms |
11636 KB |
Output is correct |
35 |
Correct |
274 ms |
9852 KB |
Output is correct |
36 |
Correct |
569 ms |
18156 KB |
Output is correct |
37 |
Correct |
25 ms |
7032 KB |
Output is correct |
38 |
Correct |
598 ms |
19128 KB |
Output is correct |
39 |
Correct |
560 ms |
19168 KB |
Output is correct |
40 |
Correct |
566 ms |
19132 KB |
Output is correct |
41 |
Correct |
556 ms |
19128 KB |
Output is correct |
42 |
Correct |
556 ms |
19268 KB |
Output is correct |
43 |
Correct |
589 ms |
19168 KB |
Output is correct |
44 |
Correct |
558 ms |
19140 KB |
Output is correct |
45 |
Correct |
568 ms |
19168 KB |
Output is correct |
46 |
Correct |
578 ms |
19148 KB |
Output is correct |
47 |
Correct |
568 ms |
19132 KB |
Output is correct |
48 |
Correct |
163 ms |
15040 KB |
Output is correct |
49 |
Correct |
195 ms |
16928 KB |
Output is correct |
50 |
Correct |
57 ms |
6392 KB |
Output is correct |
51 |
Correct |
68 ms |
8916 KB |
Output is correct |
52 |
Correct |
28 ms |
5880 KB |
Output is correct |
53 |
Correct |
248 ms |
17440 KB |
Output is correct |
54 |
Correct |
155 ms |
9772 KB |
Output is correct |
55 |
Correct |
460 ms |
15884 KB |
Output is correct |
56 |
Correct |
246 ms |
10784 KB |
Output is correct |
57 |
Correct |
314 ms |
17300 KB |
Output is correct |
58 |
Correct |
36 ms |
8748 KB |
Output is correct |
59 |
Correct |
59 ms |
7672 KB |
Output is correct |
60 |
Correct |
146 ms |
15736 KB |
Output is correct |
61 |
Correct |
166 ms |
16460 KB |
Output is correct |
62 |
Correct |
103 ms |
14032 KB |
Output is correct |
63 |
Correct |
60 ms |
11664 KB |
Output is correct |
64 |
Correct |
70 ms |
13044 KB |
Output is correct |
65 |
Correct |
107 ms |
19700 KB |
Output is correct |
66 |
Correct |
68 ms |
7672 KB |
Output is correct |
67 |
Correct |
89 ms |
16112 KB |
Output is correct |
68 |
Correct |
171 ms |
20220 KB |
Output is correct |
69 |
Correct |
33 ms |
4472 KB |
Output is correct |
70 |
Correct |
10 ms |
3064 KB |
Output is correct |
71 |
Correct |
74 ms |
11244 KB |
Output is correct |
72 |
Correct |
111 ms |
18164 KB |
Output is correct |
73 |
Correct |
230 ms |
22848 KB |
Output is correct |
74 |
Correct |
264 ms |
20112 KB |
Output is correct |
75 |
Correct |
187 ms |
22768 KB |
Output is correct |
76 |
Correct |
173 ms |
21748 KB |
Output is correct |
77 |
Correct |
263 ms |
20344 KB |
Output is correct |