• 2021.3.22


    (mathcal{A})

    [HNOI2014]世界树

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    using namespace std;
    namespace cxcyl {
    	const int N = 300300, inf = (int)1e9;
    	int n, m, rt, tp, a[N], bo[N], dfn[N], siz[N], dep[N], tn[N], up[N];
    	int f[N][21], s[N], ans[N], A[N], timer;
    	pair<int, int> g[N];
    	vector<int> G[N], E[N];
    	inline int read() {
    		int x = 0, f = 1; char c = getchar();
    		while (c > -1 && c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
    		if (c == -1) return 0;
    		while (c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
    		return x * f;
    	}
    	void dfs0(int u) {
    		for (int i = 1; i <= 20; ++i)
    			f[u][i] = f[f[u][i - 1]][i - 1];
    		dfn[u] = ++timer;
    		siz[u] = 1;
    		for (int v : G[u])
    			if (!dfn[v]) {
    				f[v][0] = u;
    				dep[v] = dep[u] + 1;
    				dfs0(v);
    				siz[u] += siz[v];
    			}
    	}
    	void dfs1(int u) {
    		g[u] = make_pair(bo[u] ? 0 : inf, u);
    		for (int v : E[u]) {
    			dfs1(v);
    			g[u] = min(g[u], make_pair(g[v].fi + dep[v] - dep[u], g[v].se));
    		}
    	}
    	void dfs2(int u, int D, int x) {
    		if (make_pair(D, x) < g[u])
    			g[u] = make_pair(D, x);
    		else {
    			D = g[u].fi;
    			x = g[u].se;
    		}
    		for (int v : E[u])
    			dfs2(v, D + dep[v] - dep[u], x);
    	}
    	void dfs3(int u) {
    		tn[u] = g[u].se;
    		ans[tn[u]] += siz[u];
    		for (int v : E[u]) {
    			int x = v;
    			for (int i = 20; i >= 0; --i)
    				if (dep[f[x][i]] > dep[u])
    					x = f[x][i];
    			ans[tn[u]] -= siz[up[v] = x];
    			dfs3(v);
    		}
    	}
    	void dfs4(int u) {
    		for (int v : E[u]) {
    			int x = up[v], y = v, H;
    			if (tn[u] == tn[v])
    				ans[tn[u]] += siz[x] - siz[v];
    			else {
    				H = dep[tn[v]] + dep[u] - g[u].first;
    				H = H & 1 ? H + 1 >> 1 : (tn[v] < tn[u] ? H >> 1 : (H >> 1) + 1);
    				for (int i = 20; i >= 0; --i)
    					if (dep[f[y][i]] >= H)
    						y = f[y][i];
    				ans[tn[v]] += siz[y] - siz[v];
    				ans[tn[u]] += siz[x] - siz[y];
    			}
    			dfs4(v);
    		}
    	}
    	void dfs5(int u) {
    		up[u] = tn[u] = 0;
    		for (int v : E[u]) dfs5(v);
    		E[u].clear();
    	}
    	inline int lca(int u, int v) {
    		if (dep[u] < dep[v]) swap(u, v);
    		int len = dep[u] - dep[v];
    		for (int i = 0; i <= 20; ++i) if (len >> i & 1) u = f[u][i];
    		for (int i = 20; i >= 0; --i) if (f[u][i] != f[v][i]) u = f[u][i], v = f[v][i];
    		return u == v ? u : f[u][0];
    	}
    	inline int main() {
    		n = read();
    		for (int i = 1; i < n; ++i) {
    			int u = read(), v = read();
    			G[u].push_back(v);
    			G[v].push_back(u);
    		}
    		dfs0(1);
    		for (int T = read(); T--; ) {
    			//clear
    			int m = read();
    			for (int i = 1; i <= m; ++i) {
    				A[i] = a[i] = read();
    				bo[a[i]] = 1;
    			}
    			sort(a + 1, a + m + 1, [](int x, int y) { return dfn[x] < dfn[y]; });
    			s[tp = 1] = a[1];
    			for (int i = 2; i <= m; ++i) {
    				int l = lca(a[i], s[tp]);
    				while (tp > 1 && dep[l] <= dep[s[tp - 1]]) {
    					E[s[tp - 1]].push_back(s[tp]);
    					--tp;
    				}
    				if (s[tp] != l) {
    					E[l].push_back(s[tp]);
    					s[tp] = l;
    				}
    				s[++tp] = a[i];
    			}
    			while (tp > 1) {
    				E[s[tp - 1]].push_back(s[tp]);
    				--tp;
    			}
    			rt = s[1];
    			dfs1(rt);
    			dfs2(rt, g[rt].fi, g[rt].se);
    			dfs3(rt);
    			dfs4(rt);
    			ans[tn[rt]] += siz[1] - siz[rt];
    			for (int i = 1; i <= m; ++i)
    				printf("%d ", ans[A[i]]);
    			puts("");
    			//clear
    			dfs5(rt);
    			for (int i = 1; i <= m; ++i)
    				bo[a[i]] = ans[a[i]] = 0;
    		}
    		return 0;
    	}
    } int main() { return cxcyl::main(); }
    
  • 相关阅读:
    思考的容器:结构
    思维的结构-结构是思维的组织形式-系统思维
    分层 抽象 复杂 认知
    NoSQL 简介
    什么是数据库ACID?
    sqlite3 多线程和锁 ,优化插入速度及性能优化
    Architecture of SQLite
    关系模型我的理解
    科学理论--抽象
    认识的三个层次
  • 原文地址:https://www.cnblogs.com/herald/p/14565303.html
Copyright © 2020-2023  润新知