Submission #1183677

#TimeUsernameProblemLanguageResultExecution timeMemory
1183677sardor_salimovTourism (JOI23_tourism)C++17
28 / 100
5094 ms19728 KiB
#include <bits/stdc++.h>
#define ar array
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;

const int N = 1e5 + 5, B = 200, lg = 17;
vector <int> g[N];
int st[lg][N], bit[N], d[N], n, m, q;
int c[N], tin[N], tout[N], tim = 0;

void dfs(int x, int par) {
	tin[x] = ++tim; st[0][x] = par; d[x] = d[par] + 1;
	for (int i = 1; i < lg; i++)
		st[i][x] = st[i - 1][st[i - 1][x]];
	for (int &y : g[x]) {
		if (y != par) {
			dfs(y, x);
		}
	}
	tout[x] = tim;
}

void upd(int i, int qx) {
	while (i <= n) {
		bit[i] += qx;
		i |= (i + 1);
	}
}

int get(int i) {
	int ans = 0;
	while (i >= 0) {
		ans += bit[i];
		i = (i & (i + 1)) - 1;
	}
	return ans;
}

int get(int l, int r) {
	return get(r) - get(l - 1);
}

int lca = -1, cnt[N], sm = 0, ans = 0;
multiset <int> mst;

void add(int x) {
	mst.insert(x);
	if (lca == -1)
		lca = x, ans++;
	if (cnt[x] == 0) {
		int sb = get(tin[x], tout[x]), nsb = sm - sb;
		if (min(sb, nsb) == 0) {
			if (nsb == 0) {
				ans += d[lca] - d[x];
				lca = x;
			} else {
				int b = 16, y = x, res = 1;
				while (b >= 0) {
					int ty = st[b][y];
					if (get(tin[ty], tout[ty]) == 0)
						y = ty, res += (1 << b);
					b--;
				}
				y = st[0][y];
				if (d[lca] > d[y]) {
					res += d[lca] - d[y];
					lca = y;
				}
				ans += res;
			}
		}
	}
	cnt[x]++, sm++, upd(tin[x], 1);
}

int nlca() {
	int y = *mst.begin(), b = 16;
	if (sm == get(tin[y], tout[y]))
		return y;
	while (b >= 0) {
		int ty = st[b][y];
		if (sm - get(tin[ty], tout[ty]) > 0)
			y = ty;
		b--;
	}
	y = st[0][y];
	return y;
}

void rem(int x) {
	mst.erase(mst.find(x));
	cnt[x]--, sm--, upd(tin[x], -1);
	if (cnt[x] == 0) {
		int sb = get(tin[x], tout[x]), nsb = sm - sb;
		if (nsb > 0 && sb > 0)
			return;
		if (sb == 0) {
			int b = 16, y = x, res = 1;
			while (b >= 0) {
				int ty = st[b][y];
				if (get(tin[ty], tout[ty]) == 0)
					y = ty, res += (1 << b);
				b--;
			}
			y = st[0][y];
			if (sm - get(tin[y], tout[y]) + cnt[y] == 0) {
				int sv = y;
				y = nlca();
				res += d[y] - d[sv];
				lca = y;
			}
			ans -= res;
		} else {
			int y = nlca();
			ans -= d[y] - d[lca];
			lca = y;
		}
	}
}

int tl = 1, tr = 0;

void correct(int l, int r) {
	while (tr < r)
		add(c[++tr]);
	while (l < tl)
		add(c[--tl]);
	while (r < tr)
		rem(c[tr--]);
	while (tl < l)
		rem(c[tl++]);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 2; i <= n; i++) {
		int u, v;
		cin >> u >> v;
		g[u].emplace_back(v);
		g[v].emplace_back(u);
	}
	for (int i = 1; i <= m; i++)
		cin >> c[i];
	dfs(1, 0);
	tout[0] = n;
	vector <ar <int, 3>> query(q);
	vector <int> res(q);
	for (int i = 0; i < q; i++)
		cin >> query[i][0] >> query[i][1], query[i][2] = i;
	sort(all(query), [] (const ar <int, 3> &a, const ar <int, 3> &b) {
		if (a[0] / B == b[0] / B)
			return a[1] < b[1];
		return a[0] / B < b[0] / B;
	});
	for (auto now : query) {
		correct(now[0], now[1]);
		res[now[2]] = ans;
	}
	for (int i : res)
		cout << i << '\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...