Submission #728268

#TimeUsernameProblemLanguageResultExecution timeMemory
728268penguin133Tourism (JOI23_tourism)C++17
100 / 100
1169 ms65976 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define pi pair<int, int>
#define pii pair<int, pi>
#define fi first
#define se second

int sz[1000005], head[1000005], par[20][100005], dep[1000005], S[1000005], E[1000005];
int up[1000005];
vector<int>v[1000005];
int n, m, q;
vector<pii>adj;
int hello = 1;
void dfs(int x, int p, int d){
	dep[x] = d;
	up[x] = p;
	sz[x] = 1;
	for(auto i : v[x]){
		if(i == p)continue;
		dfs(i, x, d + 1);
		sz[x] += sz[i];
	}
}


struct node{
	int s,e,m,val, lazy = 0, mc = 0;
	node *l, *r;
	node(int _s, int _e){
		s = _s, e = _e, m = (s + e)>>1;
		val = 0, mc = e - s + 1;
		if(s != e)l = new node(s, m), r = new node(m+1, e);
	}
	void propo(){
		if(lazy){
			val += lazy;
			if(s != e)l->lazy += lazy, r->lazy += lazy;
			lazy = 0;
		}
	}
	
	pi comb(pi a, pi b){
		pi ans;
		ans.fi = min(a.fi, b.fi);
		if(a.fi == b.fi)ans.se = a.se + b.se;
		else ans.se = (a.fi < b.fi ? a.se : b.se);
		return ans;
	}
	
	void upd(int a, int b, int c){
		//cerr << "UPD " << a << " " << b << " " << c << '\n';
		if(a == s && b == e)lazy += c;
		else{
			if(b <= m)l->upd(a, b, c);
			else if(a > m)r->upd(a, b, c);
			else l->upd(a, m, c), r->upd(m+1, b, c);
			l->propo(), r->propo();
			//val = l->val + r->val;
			val = min(l->val, r->val);
			if(l->val == r->val)mc = l->mc + r->mc;
			else mc = (l->val < r->val ? l->mc : r->mc);
		}
	}
	pi query(int a, int b){
		propo();
		if(a == s && b == e)return {val, mc};
		else if( b <= m)return l->query(a, b);
		else if(a > m)return r->query(a, b);
		else return comb(l->query(a, m), r->query(m+1, b));
	}
}*root;
int cnt = 1;
void dfs2(int x, int h, int par){
	S[x] = cnt++;
	head[x] = h;
	int maxi = 0, in = -1;
	for(auto i : v[x]){
		if(i == par)continue;
		if(maxi < sz[i])maxi = sz[i], in = i;
	}
	for(auto i : v[x]){
		if(i == par)continue;
		if(i == in)dfs2(i, h, x);
	}
	for(auto i : v[x]){
		if(i != par && i != in)dfs2(i, i, x);
	}
	E[x] = cnt-  1;
}


/*
int query(int a, int b) {
    int res = 0;
    for (; head[a] != head[b]; b = up[head[b]]) {
        if (dep[head[a]] > dep[head[b]])
            swap(a, b);
        int cur_heavy_path_max = root->query(S[head[b]], S[b]);
        res += cur_heavy_path_max;
    }
    if (dep[a] > dep[b])
        swap(a, b);
    res += root->query(S[a], S[b]);
    return res;
}
void st(int x, int a){
	if(S[x] <= S[hello] && E[hello] <= E[x]){
		int in = -1;
		for(auto i : v[x]){
			if(S[i] <= S[hello] && E[hello] <= E[i] && S[i] > S[x])in = i;
		}
		root->upd(1, n, a);
		if(in != -1)root->upd(S[in], E[in], -a);
	}
	else root->upd(S[x], E[x], a);
}
int qu(int x){
	int res=  0;
	if(S[x] <= S[hello] && E[hello] <= E[x]){
		int in = -1;
		for(auto i : v[x]){
			if(S[i] <= S[hello] && E[hello] <= E[i] && S[i] > S[x])in = i;
		}
		root->propo();
		res = root->val;
		if(in != -1)res -= root->query(S[in], E[in]);
		return res;
	}
	else return root->query(S[x], E[x]);
}
*/
int C[100005], ans[100005];
vector <pi> qu[100005];
set <pii> s;

int ft[100005];

void upd(int p, int v){
	for(;p<=m;p+=(p & -p))ft[p] += v;
}

int qry(int p){
	int res = 0;
	for(;p;p-=(p & -p))res += ft[p];
	return res;
}

void ins(int l, int r, int i){
	auto it = s.upper_bound({l-1, {1e9, 1e9}});
	vector <pii> sad, nw;
	if(it != s.begin()){
		it--;
		pii tmp = *it;
		if(tmp.se.fi < l)it++;
		else{
			nw.push_back({tmp.fi, {l - 1, tmp.se.se}});
			int x = tmp.se.se;
			if(tmp.se.fi > r){
				nw.push_back({r+1, {tmp.se.fi, tmp.se.se}});
			}
			upd(x, - (min(r, tmp.se.fi) - l + 1));
			sad.push_back(tmp);
			it++;
		}
	}
	while(it != s.end()){
		pii tmp = *it;
		if(tmp.fi > r)break;
		if(tmp.se.fi > r){
			nw.push_back({r+1, {tmp.se.fi, tmp.se.se}});
			int x = tmp.se.se;
			upd(x, -(r - tmp.fi + 1));
			sad.push_back(tmp);
			break;
		}
		sad.push_back(tmp);
		int x = tmp.se.se;
		upd(x, - (tmp.se.fi - tmp.fi + 1));
		it++;
	}
	s.insert({l, {r, i}});
	upd(i, r - l + 1);
	for(auto j : sad)s.erase(j);
	for(auto j : nw)s.insert(j);
}

void chng(int a, int b, int c) {
    for (; head[a] != head[b]; b = up[head[b]]) {
		//cerr << a << " " << b << " " << head[a] << " " << head[b] << '\n';
        if (dep[head[a]] > dep[head[b]])
            swap(a, b);
       // root->upd(S[head[b]], S[b], c);
       ins(S[head[b]], S[b], c);
    }
    if (dep[a] > dep[b])
        swap(a, b);
    //root->upd(S[a], S[b], c);
    ins(S[a], S[b], c);
}

int32_t main(){
	ios::sync_with_stdio(0);cin.tie(0);
	cin >> n >> m >> q;
	for(int i=1;i<n;i++){
		int a, b; cin >> a >> b;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	for(int i=1;i<=m;i++)cin >> C[i];
	root= new node(1, n);
	dfs(1, -1, 1);
	dfs2(1, 1, -1);
	for(int i=1;i<=q;i++){
		int a, b; cin >> a >> b;
		qu[b].push_back({a, i});
	}
	for(auto [i, j] : qu[1])ans[j] = 1;
	s.insert({1, {n, 1}});
	upd(1, n);
	for(int i=2;i<=m;i++){
		chng(C[i], C[i-1], i);
		for(auto [j, k] : qu[i]){
			ans[k] = n - qry(j);
		}
	}
	for(int i=1;i<=q;i++)cout << max(1ll, ans[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...