zoukankan      html  css  js  c++  java
  • POJ 3237 Tree 树链剖分

    树链剖分基础题

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 10010;
    struct edge
    {
    	int v, next;
    }e[maxn*2];
    int first[maxn], cnt;
    
    int top[maxn], dep[maxn], sz[maxn], f[maxn], son[maxn], rank[maxn], tid[maxn];
    int tp, tim;
    int d[maxn][3];
    int n;
    void AddEdge(int u, int v)
    {
    	e[cnt].v = v;
    	e[cnt].next = first[u];
    	first[u] = cnt++;
    	
    	e[cnt].v = u;
    	e[cnt].next = first[v];
    	first[v] = cnt++;
    	
    }
    void init()
    {
    	memset(first, -1, sizeof(first));
    	cnt = 1;
    	memset(son, -1, sizeof(son));
    	tim = 0;
    }
    
    void dfs1(int u, int fa, int d)
    {
    	sz[u] = 1;
    	dep[u] = d;
    	f[u] = fa;	
    	for(int i = first[u]; i != -1; i = e[i].next)
    	{
    		int v = e[i].v;
    		if(v == fa)
    			continue;
    		dfs1(v, u, d+1);
    		sz[u] += sz[v];
    		if(son[u] == -1 || sz[son[u]] < sz[v])
    			son[u] = v;
    	}
    }
    
    void dfs2(int u, int tp)
    {
    	top[u] = tp;
    	tid[u] = ++tim;
    	rank[tid[u]] = u;
    	if(son[u] == -1)
    		return;
    	dfs2(son[u], tp);
    	for(int i = first[u]; i != -1; i = e[i].next)
    	{
    		int v = e[i].v;
    		if(v != f[u] && son[u] != v)
    			dfs2(v, v);
    	}
    }
    
    int ma[maxn<<2];
    int mi[maxn<<2];
    int lz[maxn<<2];
    void pushup(int l, int r, int rt)
    {
    	ma[rt] = max(ma[rt<<1], ma[rt<<1|1]);
    	mi[rt] = min(mi[rt<<1], mi[rt<<1|1]);
    }
    void build(int l, int r, int rt)
    {	
    	ma[rt] = 0;
    	mi[rt] = 0;
    	lz[rt] = 0;
    	if(l == r)
    	{
    		return;
    	}
    	int m = (l + r) >> 1;
    	build(l, m, rt<<1);
    	build(m+1, r, rt<<1|1);
    }
    void pushdown(int l, int r, int rt)
    {
    	if(l == r)
    		return;
    	if(lz[rt])
    	{
    		mi[rt<<1] = -mi[rt<<1];
    		ma[rt<<1] = -ma[rt<<1];
    		swap(mi[rt<<1], ma[rt<<1]);
    		mi[rt<<1|1] = -mi[rt<<1|1];
    		ma[rt<<1|1] = -ma[rt<<1|1];
    		swap(mi[rt<<1|1], ma[rt<<1|1]);	
    		lz[rt<<1] ^= 1;
    		lz[rt<<1|1] ^= 1;
    		lz[rt] = 0;
    	}
    }
    void update(int x, int y, int l, int r, int rt)
    {
    	if(x == l && y == r)
    	{
    		mi[rt] = -mi[rt];
    		ma[rt] = -ma[rt];
    		swap(mi[rt], ma[rt]);
    		lz[rt] ^= 1;
    		return;
    	}
    	pushdown(l, r, rt);
    	int m = (l + r) >> 1;
    	if(y <= m)
    		update(x, y, l, m, rt<<1);
    	else if(x > m)
    		update(x, y, m+1, r, rt<<1|1);
    	else
    	{
    		update(x, m, l, m, rt<<1);
    		update(m+1, y, m+1, r, rt<<1|1);
    	}
    	pushup(l, r, rt);
    }
    void update2(int x, int l, int r, int rt, int w)
    {
    	if(l == r)
    	{
    		ma[rt] = mi[rt] = w;
    		lz[rt] = 0;
    		return;
    	}
    	pushdown(l, r, rt);
    	int m = (l + r) >> 1;
    	if(x <= m)
    		update2(x, l, m, rt<<1, w);
    	else
    		update2(x, m+1, r, rt<<1|1, w);
    	pushup(l, r, rt);
    }
    int query(int x, int y, int l, int r, int rt)
    {
    	if(l == x && r == y)
    		return ma[rt];
    	pushdown(l, r, rt);
    	
    	int m = (l + r) >> 1;
    	if(y <= m)
    		return query(x, y, l, m, rt<<1);
    	else if(x > m)
    		return query(x, y, m+1, r, rt<<1|1);
    	else
    	{
    		return max(query(x, m, l, m, rt<<1), query(m+1, y, m+1, r, rt<<1|1));
    	}
    }
    
    void change(int u, int v)
    {
    	while(top[u] != top[v])
    	{
    		if(dep[top[u]] < dep[top[v]])
    			swap(u, v);
    		update(tid[top[u]], tid[u], 1, n, 1);
    		u = f[top[u]];
    	}
    	if(u == v)
    		return;
    	if(dep[u] > dep[v])
    		swap(u, v);
    	update(tid[son[u]], tid[v], 1, n, 1);
    }
    int find(int u, int v)
    {
    	int ans = -999999999;
    	while(top[u] != top[v])
    	{
    		if(dep[top[u]] < dep[top[v]])
    			swap(u, v);
    		ans = max(ans, query(tid[top[u]], tid[u], 1, n, 1));
    		u = f[top[u]];
    	}
    	if(u == v)
    		return ans;
    	if(dep[u] > dep[v])
    		swap(u, v);
    	ans = max(ans, query(tid[son[u]], tid[v], 1, n, 1));
    	return ans;
    }
    int main()
    {
    	int T;
    	scanf("%d", &T);
    	while(T--)
    	{
    		init();
    		
    		scanf("%d", &n);
    		for(int i = 1; i < n; i++)
    		{
    			int u, v, w;
    			scanf("%d %d %d", &u, &v, &w);
    			AddEdge(u, v);
    			d[i][0] = u;
    			d[i][1] = v;
    			d[i][2] = w;
    		}
    		dfs1(1, 0, 0);
    		dfs2(1, 1);
    		build(1, n, 1);
    		
    		for(int i = 1; i < n; i++)
    		{
    			if(dep[d[i][0]] > dep[d[i][1]])
    				swap(d[i][0], d[i][1]);
    			update2(tid[d[i][1]], 1, n, 1, d[i][2]);
    		}
    		char s[10];
    		while(scanf("%s", s) && strcmp(s, "DONE"))
    		{
    			if(s[0] == 'Q')
    			{
    				int x, y;
    				scanf("%d %d", &x, &y);
    				printf("%d
    ", find(x, y));
    			}
    			else if(s[0] == 'C')
    			{
    				int x, y;
    				scanf("%d %d", &x, &y);
    				update2(tid[d[x][1]], 1, n, 1, y);
    			}
    			else
    			{
    				int x, y;
    				scanf("%d %d", &x, &y);
    				change(x, y);
    			}
    		}
    	} 
    	return 0;
    }
    


  • 相关阅读:
    软件序列号搜索引擎
    javascript获取url以及jquery获取url参数的方法
    TrueCrypt 一款免费开源的加密软件
    nuit中文文档
    FineUploader 结合 一般处理程序 【上传示例】
    新浪CDN加速类库.
    C#整合VS2010和NUnit
    zencoding更名emmet了.
    visual studio 主题下载网站
    win8无法使用内置管理员账户打开 解决办法
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7064387.html
Copyright © 2011-2022 走看看