#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define int ll
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef vector<vii> vvii;
#define INF INT_MAX
#define MOD 1000000007
#define all(x) x.begin(), x.end()
class SegTree{
vi st; int l, r;
void build(int node, int l, int r){
if(l == r){
st[node] = l;
return;
}
int m = (l + r) / 2;
build(node*2, l, m);
build(node*2+1, m+1, r);
st[node] = max(st[node*2], st[node*2+1]);
return;
}
void Update(int node, int l, int r, int L, int R){
if(r < L or R < l) return;
if(L <= l and r <= R){
st[node] = (st[node]==-1?l:-1);
return;
}
int m = (l+r)>>1;
Update(node*2, l, m, L, R);
Update(node*2+1, m+1, r, L, R);
st[node] = max(st[node*2], st[node*2+1]);
return;
}
int Query(int node, int l, int r, int L, int R){
if(r < L or R < l) return -1;
if(L <= l and r <= R) return st[node];
int m = (l+r)>>1;
int v2 = Query(node*2+1, m+1, r, L, R);
if(v2 == -1) return Query(node*2, l, m, L, R);
return v2;
}
public:
SegTree(int l, int r){
int sz = (r-l+1);
st = vi(4*sz);
this->l = l, this->r = r;
build(1, l, r);
}
void Update(int L, int R){
Update(1, l, r, L, R);
return;
}
int Query(int L, int R){
return Query(1, l, r, L, R);
}
};
class HLD{
vi heavy, head, pos; // [next node, root of chain, index]
vi parent, depth;
int pos_timer = 0;
SegTree ST;
vi ppos, val, prev;
int dfs(int u, const vvi &adj){
int subtree_size = 1, max_size = 0;
for(auto v : adj[u]){
if(v == parent[u]) continue;
parent[v] = u, depth[v] = depth[u]+1;
int child_subtree_size = dfs(v, adj);
subtree_size += child_subtree_size;
if(max_size < child_subtree_size){
max_size = child_subtree_size;
heavy[u] = v;
}
}
return subtree_size;
}
void decompose(int u, int h, const vvi &adj){
head[u] = h; pos[u] = pos_timer++;
ppos[pos[u]] = u;
if(heavy[u] != -1)
decompose(heavy[u], h, adj);
for(auto v : adj[u]){
if(v == parent[u] || v == heavy[u]) continue;
decompose(v, v, adj);
}
return;
}
int find_root(int u){
for(int a = u; ; a = parent[head[a]]){
int qry = ST.Query(pos[head[a]], pos[a]);
if(qry == -1) continue;
int x = ppos[qry];
return x;
}
// impossible case
assert(false);
return -1;
}
public:
HLD(const vvi &adj) : ST(0, adj.size()-1){
int N = adj.size(); // !!0 based indexing!!
heavy = vi(N, -1), head = vi(N), pos = vi(N);
parent = vi(N), depth = vi(N);
ppos = vi(N), val = vi(N, 1), prev = vi(N);
dfs(0, adj);
decompose(0, 0, adj);
}
void Update(int u, int v){
if(depth[u] > depth[v]) swap(u, v);
if(ST.Query(pos[v], pos[v]) != -1){
int par = find_root(u);
val[par] += val[v]-prev[v];
}else{
int par = find_root(u);
prev[v] = val[v] = val[par];
}
ST.Update(pos[v], pos[v]);
return;
}
int Query(int u){
return val[find_root(u)];
}
};
signed main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
int N, M, Q; cin >> N >> M >> Q;
vii J(N); vvi adj(N);
for(int x = 0; x < N-1; x++){
int u, v; cin >> u >> v;
u--, v--;
J[x] = {u, v};
adj[u].push_back(v);
adj[v].push_back(u);
}
HLD hvt(adj);
while(M--){
int i; cin >> i; i--;
hvt.Update(J[i].first, J[i].second);
}
while(Q--){
int u; cin >> u; u--;
cout << hvt.Query(u) << endl;
}
return 0;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
384 KB |
Output is correct |
2 |
Correct |
1 ms |
384 KB |
Output is correct |
3 |
Correct |
1 ms |
384 KB |
Output is correct |
4 |
Correct |
1 ms |
384 KB |
Output is correct |
5 |
Correct |
1 ms |
512 KB |
Output is correct |
6 |
Correct |
2 ms |
512 KB |
Output is correct |
7 |
Correct |
21 ms |
2304 KB |
Output is correct |
8 |
Correct |
20 ms |
2304 KB |
Output is correct |
9 |
Correct |
20 ms |
2304 KB |
Output is correct |
10 |
Correct |
370 ms |
20052 KB |
Output is correct |
11 |
Correct |
380 ms |
19832 KB |
Output is correct |
12 |
Correct |
312 ms |
28664 KB |
Output is correct |
13 |
Correct |
290 ms |
19564 KB |
Output is correct |
14 |
Correct |
295 ms |
19192 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
143 ms |
23924 KB |
Output is correct |
2 |
Correct |
138 ms |
23668 KB |
Output is correct |
3 |
Correct |
109 ms |
28024 KB |
Output is correct |
4 |
Correct |
112 ms |
27896 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
384 KB |
Output is correct |
2 |
Correct |
1 ms |
384 KB |
Output is correct |
3 |
Correct |
1 ms |
384 KB |
Output is correct |
4 |
Correct |
1 ms |
384 KB |
Output is correct |
5 |
Correct |
1 ms |
384 KB |
Output is correct |
6 |
Correct |
4 ms |
640 KB |
Output is correct |
7 |
Correct |
43 ms |
3200 KB |
Output is correct |
8 |
Correct |
531 ms |
29304 KB |
Output is correct |
9 |
Correct |
531 ms |
29304 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
552 ms |
29328 KB |
Output is correct |
2 |
Correct |
350 ms |
28896 KB |
Output is correct |
3 |
Correct |
359 ms |
29176 KB |
Output is correct |
4 |
Correct |
377 ms |
29048 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
384 KB |
Output is correct |
2 |
Correct |
1 ms |
384 KB |
Output is correct |
3 |
Correct |
1 ms |
384 KB |
Output is correct |
4 |
Correct |
2 ms |
384 KB |
Output is correct |
5 |
Correct |
5 ms |
512 KB |
Output is correct |
6 |
Correct |
46 ms |
2304 KB |
Output is correct |
7 |
Correct |
659 ms |
20728 KB |
Output is correct |
8 |
Correct |
558 ms |
29432 KB |
Output is correct |
9 |
Correct |
496 ms |
20844 KB |
Output is correct |
10 |
Correct |
629 ms |
20472 KB |
Output is correct |
11 |
Correct |
398 ms |
25076 KB |
Output is correct |
12 |
Correct |
397 ms |
25204 KB |
Output is correct |
13 |
Correct |
352 ms |
29176 KB |
Output is correct |