[HNOI2016]树-缩点+倍增lca+主席树(码农)

版权声明:蒟蒻的博文,dalao转载标明出处就好吖 https://blog.csdn.net/jokingcoder/article/details/89460691

传送门
博主心态已崩,打到一半在打啥都不知道
所以先挖坑,等心态恢复好了继续打
专业挖坑不填100年

#include <cstdio>
using namespace std;
struct TemplateTree {
	int tot = 0, lst[N], size[N], dfn[N], dep[N];
	
	struct Edge{
		int to, nxt;
	}e[N << 1];
	
	inline void add(int u, int v) {
		e[++cnt].to = v;
		e[cnt].nxt = lst[u];
		lst[u] = cnt;
	}
	
	inline void dfs(int x, int fa) {
		dfn[x] = ++tot;
		rk[tot] = x;
		size[x] = 1;
		dep[x] = dep[fa] + 1;
		for (int i = lst[x]; i; i = e[i].nxt) {
			int son = e[i].to;
			if (son == fa) continue;
			dfs(son, x);
			size[x] += size[son];
		}
	}
}tem;

struct ChairmanTree{
	struct Node{
		Node *ls, *rs;
		int sum;
		Node(Node *l = NULL, Node *r = NULL, int x = 0) {
			ls = l;
			rs = r;
			sum = x;
		}
	}*rt[N];
	
	inline void build(Node *&rt, int l, int r) {
		if (!rt) {
			rt = new Node();
		}
		if (l == r) return;
		int mid = l + r >> 1;
		build(rt -> ls, l, mid);
		build(rt -> rs, mid + 1, r);
	}
	
	inline Node *modify(Node *rt, int l, int r, int p) {
		Node *now = new Node(rt -> ls, rt -> rs, rt -> sum + 1);
		if (l == r) return now;
		int mid = l + r >> 1;
		if (p <= mid) now -> ls = modify(now -> ls, l, mid, p);
		else now -> rs = modify(now -> rs, mid + 1, r, p);
		return now;
	}
	
	inline int query(Node *L, Node *R, int l, int r, int kth) {
		if (l == r) return l;
		int mid = l + r >> 1, x = R -> ls -> sum - L -> ls -> sum;
		if (x >= kth) query(L -> ls, R -> ls, l, mid, kth);
		else query(L -> rs, R -> rs, mid + 1, rs, kth);
	}
	
	inline void make(*a) {
		for (int i = 1; i <= n; ++i) {
			rt[i] = modify(rt[i - 1], 1, n, a[i]);
		}
	}
}cmt;

struct BigTree{
	int all, id[N], ont[N];
	LL len[N];
	
	inline void doit(int wh, int x, int kth) {
		id[++all] = nds + 1;
		nds += tem.size[x];
		ont[all] = x;
		c[all][0] = wh;
		len[all][0] = cmt.dep[cmt.query(cmt.rt[cmt.dfn[x] - 1], cmt.rt[cmt.dfn[x] + cmt.size[x] - 1], 1, n, kth)];
		for (int i = 1; i < L; ++i) {
			c[all][i] = c[c[all][i - 1]][i - 1];
			len[all][i] = len[c[all][i - 1]][i - 1] + len[all][i - 1];
		}
	}
	
	inline LL query(LL x, LL y) {
		int xx = upper_bound(id + 1, id + all + 1, x) - id - 1;
		int yy = upper_bound(id + 1, id + all + 1, y) - id - 1;
		
	}
}bt;

int main() {
	scanf("%d%d%d", &n, &m, &q);
	for (int i = 1, x, y; i <= n; ++i) {
		scanf("%d%d", &x, &y);
		tem.add(x, y);
		tem.add(y, x);
	}
	tem.dfs(1, 0);
	cmt.build(rt[0], 1, n);
	cmt.make(tem.rk);
	bt.doit(1, 1, 1);
	for (int i = 1; i <= m; ++i) {
		int a;
		LL b;
		scanf("%d%lld", &a, &b);
		int id = upper_bound(bt.id + 1, bt.id + bt.all + 1, b) - bt.id - 1;
		bt.doit(id, a, b - bt.id[id] + 1);
	}
	while (q--) {
		LL fr, to
		scanf("%lld%lld", &fr, &to);
		printf("%lld\n", bt.query(fr, to));
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jokingcoder/article/details/89460691