zoukankan      html  css  js  c++  java
  • 【JZOJ3397】【GDOI2014模拟】雨天的尾巴

    题目大意

    给你一棵(n)个点的树,有(m)个操作,每次操作将(x)(y)的路径上的每个点都放入一个颜色为(z)的球。你需要求出最后每个点里个数最多的球是哪种颜色的。

    分析

    通过树链剖分把树上路径转化为若干区间,把树上问题转化为区间问题,然后结合差分思想,在左端点加上(+z)标记,在右端点(+1)的位置加上(-z)标记,我们从左往右做,用线段树维护当前出现次数最多的颜色,时间复杂度(O(nlog^2n))。最好将颜色离散化,这样线段树就不必动态开点了。

    Code

    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define lson rt << 1
    #define rson rt << 1 | 1
    using namespace std;
    
    const int N = 100007;
    
    int n, m, len, x[N], y[N], z[N], arr[N], ans[N];
    int tot, cnt, st[N], to[N << 1], nx[N << 1], son[N], top[N], dfn[N], fa[N], size[N], ord[N], dep[N];
    void add(int u, int v) { to[++tot] = v, nx[tot] = st[u], st[u] = tot; }
    vector<int> lis[N];
    
    void dfs(int u)
    {
    	size[u] = 1;
    	for (int i = st[u]; i; i = nx[i])
    		if (to[i] != fa[u])
    		{
    			dep[to[i]] = dep[u] + 1, fa[to[i]] = u, dfs(to[i]), size[u] += size[to[i]];
    			if (size[to[i]] > size[son[u]]) son[u] = to[i];
    		}
    }
    void dfs2(int u, int tp)
    {
    	dfn[u] = ++cnt, ord[cnt] = u, top[u] = tp;
    	if (son[u]) dfs2(son[u], tp);
    	for (int i = st[u]; i; i = nx[i]) if (to[i] != fa[u] && to[i] != son[u]) dfs2(to[i], to[i]);
    }
    struct note { int id, cnt; } tr[N * 4];
    note max(note a, note b)
    {
    	if (a.cnt == b.cnt) return a.id < b.id ? a : b;
    	return a.cnt > b.cnt ? a : b;
    }
    void build(int rt, int l, int r)
    {
    	if (l == r) { tr[rt] = (note){l, 0}; return; }
    	int mid = l + r >> 1;
    	build(lson, l, mid), build(rson, mid + 1, r);
    }
    void ins(int rt, int l, int r, int po, int v)
    {
    	if (l == r) { tr[rt].cnt += v; return; }
    	int mid = l + r >> 1;
    	if (po <= mid) ins(lson, l, mid, po, v);
    	else ins(rson, mid + 1, r, po, v);
    	tr[rt] = max(tr[lson], tr[rson]);
    }
    
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for (int i = 1, u, v; i < n; i++) scanf("%d%d", &u, &v), add(u, v), add(v, u);
    	dep[1] = 1, dfs(1), dfs2(1, 1);
    	for (int i = 1; i <= m; i++) scanf("%d%d%d", &x[i], &y[i], &z[i]), arr[++len] = z[i];
    	sort(arr + 1, arr + len + 1);
    	len = unique(arr + 1, arr + len + 1) - arr - 1;
    	for (int i = 1, u, v, w; i <= m; i++)
    	{
    		u = x[i], v = y[i], w = lower_bound(arr + 1, arr + len + 1, z[i]) - arr;
    		while (top[u] != top[v])
    		{
    			if (dep[top[u]] < dep[top[v]]) swap(u, v);
    			lis[dfn[top[u]]].push_back(w), lis[dfn[u] + 1].push_back(-w);
    			u = fa[top[u]];
    		}
    		if (dep[u] < dep[v]) swap(u, v);
    		lis[dfn[v]].push_back(w), lis[dfn[u] + 1].push_back(-w);
    	}
    	build(1, 1, len);
    	for (int i = 1; i <= n; i++)
    	{
    		int sz = lis[i].size();
    		for (int j = 0, k; j < sz; j++)
    		{
    			k = lis[i][j];
    			if (k > 0) ins(1, 1, len, k, 1);
    			else ins(1, 1, len, -k, -1);
    		}
    		ans[ord[i]] = arr[tr[1].cnt ? tr[1].id : 0];
    	}
    	for (int i = 1; i <= n; i++) printf("%d
    ", ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    配色方案及色彩心理学(转)
    CSS中强大的EM
    Link To Sql简单
    改变html中鼠标形状
    JS实现雪花效果
    你真的已经搞懂JavaScript了吗?
    MVC特性
    初识 bower(一)
    学习前端模板引擎 jade (一)
    日志系统
  • 原文地址:https://www.cnblogs.com/zjlcnblogs/p/11178605.html
Copyright © 2011-2022 走看看