Submission #758104

#TimeUsernameProblemLanguageResultExecution timeMemory
758104MetalPowerRailway (BOI17_railway)C++14
100 / 100
303 ms32552 KiB
#include <bits/stdc++.h> using namespace std; #define pii pair<int, int> #define fi first #define se second const int MX = 2e5 + 10; const int LG = 19; struct segtree{ int st[MX << 1]; void upd(int l, int r, int v){ for(l += MX, r += MX + 1; l < r; l >>= 1, r >>= 1){ if(l & 1) st[l++] += v; if(r & 1) st[--r] += v; } } int que(int p){ int res = 0; for(p += MX; p > 0; p >>= 1) res += st[p]; return res; } } S; struct segversion{ int st[MX << 1]; void upd(int l, int r, int v){ for(l += MX, r += MX + 1; l < r; l >>= 1, r >>= 1){ if(l & 1) st[l++] = v; if(r & 1) st[--r] = v; } } int que(int p){ int res = 0; for(p += MX; p > 0; p >>= 1) res = max(res, st[p]); return res; } } T; vector<int> adj[MX]; int N, M, K, par[MX], head[MX], sp[MX][LG]; int sz[MX], dep[MX], in[MX], out[MX], tim = 0; void dfs(int u, int v){ if(v != 0) adj[u].erase(find(adj[u].begin(), adj[u].end(), v)); sz[u] = 1; dep[u] = dep[v] + 1; sp[u][0] = par[u] = v; for(int i = 1; i < LG; i++) sp[u][i] = sp[sp[u][i - 1]][i - 1]; for(int& nxt : adj[u]){ dfs(nxt, u); sz[u] += sz[nxt]; if(sz[nxt] > sz[adj[u][0]]) swap(nxt, adj[u][0]); } } void dfs2(int u){ in[u] = ++tim; for(int nxt : adj[u]){ if(nxt == adj[u][0]) head[nxt] = head[u]; else head[nxt] = nxt; dfs2(nxt); } out[u] = tim; } void init(){ dfs(1, 0); head[1] = 1; dfs2(1); } int lca(int u, int v){ if(dep[u] > dep[v]) swap(u, v); int df = dep[v] - dep[u]; for(int j = 0; j < LG; j++){ if(df >> j & 1) v = sp[v][j]; } if(u == v) return u; for(int j = LG - 1; j >= 0; j--){ if(sp[u][j] != sp[v][j]){ u = sp[u][j]; v = sp[v][j]; } } return sp[u][0]; } void upd(int u, int v, int val){ for(; head[u] != head[v]; v = par[head[v]]){ if(dep[u] > dep[v]) swap(u, v); S.upd(in[head[v]], in[v], 1); T.upd(in[head[v]], in[v], val); } if(dep[u] > dep[v]) swap(u, v); S.upd(in[u], in[v], 1); T.upd(in[u], in[v], val); } vector<pair<pii, int>> edges; int find_rep(int u, int root, int ver){ // find ancestor of u that is lower than root and off for(int i = LG - 1; i >= 0; i--){ if(dep[sp[u][i]] > dep[root] && T.que(in[sp[u][i]]) != ver) u = sp[u][i]; } return u; } int idx_edge[MX]; int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> N >> M >> K; for(int i = 1; i < N; i++){ int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); edges.push_back({{u, v}, i}); } init(); for(auto edge : edges){ if(dep[edge.fi.fi] > dep[edge.fi.se]) idx_edge[edge.fi.fi] = edge.se; else if(dep[edge.fi.fi] < dep[edge.fi.se]) idx_edge[edge.fi.se] = edge.se; } for(int i = 1; i <= M; i++){ int s; cin >> s; vector<int> curr; int root = -1; for(int j = 1; j <= s; j++){ int nd; cin >> nd; if(root == -1) root = nd; else root = lca(root, nd); curr.push_back(nd); } T.upd(in[root], in[root], i); for(int x : curr){ if(x == root || T.que(in[x]) == i) continue; int nd = find_rep(x, root, i); upd(x, nd, i); } } vector<int> answ; for(int i = 1; i <= N; i++){ if(S.que(in[i]) >= K) answ.push_back(idx_edge[i]); } sort(answ.begin(), answ.end()); cout << answ.size() << '\n'; for(int x : answ) cout << x << " "; cout << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...