zoukankan      html  css  js  c++  java
  • SPOJ QTREE7

    题意

    一棵树,每个点初始有个点权和颜色
    (0 u) :询问所有(u,v) 路径上的最大点权,要满足(u,v) 路径上所有点的颜色都相同
    $1 u (:反转)u$ 的颜色
    (2 u w) :把(u) 的点权改成(w)
    (color_i∈[0,1],w_i∈[−10^9,10^9],n,m≤10^5)

    Sol

    (LCT)
    (QTREE6)一样,黑白两棵(LCT)
    不过这次我们用数据结构维护虚子树内的最大权的同色点
    可以用(multiset),但我还是习惯可删除的(priority\_queue)
    然后每个点维护一下所有子树的最大权的同色点

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int _(1e5 + 5);
    const int INF(2e9);
    typedef int Arr[_];
    
    IL int Input(){
    	RG int x = 0, z = 1; RG char c = getchar();
    	for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    	for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    	return x * z;
    }
    
    Arr w;
    struct Heap{
    	priority_queue <int> A, B;
    
    	IL void Push(RG int x){
    		A.push(x);
    	}
    
    	IL void Del(RG int x){
    		B.push(x);
    	}
    
    	IL int Top(){
    		while(!B.empty() && B.top() == A.top()) A.pop(), B.pop();
    		return A.empty() ? -INF : A.top();
    	}
    };
    
    struct LCT{
    	Arr fa, ch[2], mxv;
    	Heap mx[_];
    	
    	IL int Son(RG int x){
    		return ch[1][fa[x]] == x;
    	}
    
    	IL int Isroot(RG int x){
    		return ch[0][fa[x]] != x && ch[1][fa[x]] != x;
    	}
    	
    	IL void Update(RG int x){
    		mxv[x] = max(max(mxv[ch[0][x]], mxv[ch[1][x]]), max(w[x], mx[x].Top()));
    	}
    
    	IL void Rotate(RG int x){
    		RG int y = fa[x], z = fa[y], c = Son(x);
    		if(!Isroot(y)) ch[Son(y)][z] = x; fa[x] = z;
    		ch[c][y] = ch[!c][x], fa[ch[c][y]] = y;
    		ch[!c][x] = y, fa[y] = x, Update(y);
    	}
    
    	IL void Splay(RG int x){
    		for(RG int y = fa[x]; !Isroot(x); Rotate(x), y = fa[x])
    			if(!Isroot(y)) Son(x) ^ Son(y) ? Rotate(x) : Rotate(y);
    		Update(x);
    	}
    
    	IL void Access(RG int x){
    		for(RG int y = 0; x; y = x, x = fa[x]){
    			Splay(x);
    			mx[x].Push(mxv[ch[1][x]]), mx[x].Del(mxv[y]);
    			ch[1][x] = y, Update(x);
    		}
    	}
    
    	IL int Findroot(RG int x){
    		Access(x), Splay(x);
    		while(ch[0][x]) x = ch[0][x];
    		Splay(x);
    		return x;
    	}
    
    	IL void Link(RG int x, RG int y){
    		if(!y) return;
    		Access(y), Splay(x), Splay(y);
    		fa[x] = y, ch[1][y] = x, Update(y);
    	}
    
    	IL void Cut(RG int x, RG int y){
    		if(!y) return;
    		Access(x), Splay(x);
    		ch[0][x] = fa[ch[0][x]] = 0, Update(x);
    	}
    } T[2];
    Arr fa, col;
    int n, m;
    vector <int> G[_];
    
    IL void Dfs(RG int u, RG int ff){
    	for(RG int i = 0, l = G[u].size(); i < l; ++i){
    		RG int v = G[u][i];
    		if(v == ff) continue;
    		T[col[v]].Link(v, u), fa[v] = u;
    		Dfs(v, u);
    	}
    }
    
    int main(RG int argc, RG char *argv[]){
    	n = Input();
    	for(RG int i = 1; i < n; ++i){
    		RG int u = Input(), v = Input();
    		G[u].push_back(v), G[v].push_back(u);
    	}
    	for(RG int i = 1; i <= n; ++i) col[i] = Input();
    	for(RG int i = 1; i <= n; ++i) w[i] = Input();
    	T[0].mxv[0] = T[1].mxv[0] = -INF;
    	Dfs(1, 0), m = Input();
    	for(RG int i = 1; i <= m; ++i){
    		RG int op = Input(), x = Input(), ff, v, &c = col[x];
    		if(op == 1) T[c].Cut(x, fa[x]), c ^= 1, T[c].Link(x, fa[x]);
    		else if(op == 2){
    			v = Input(), T[c].Access(x), T[c].Splay(x);
    			w[x] = v, T[c].Update(x);
    		}
    		else{
    			T[c].Access(x), ff = T[c].Findroot(x);
    			if(col[ff] == c) printf("%d
    ", T[c].mxv[ff]);
    			else printf("%d
    ", T[c].mxv[T[c].ch[1][ff]]);
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    封装、权限修饰符、包、构造器
    从Discuz!NT v2.0扣出来的生成静态页面的方法
    C#中struct与class的区别
    Asp.Net中虚拟文件系统的使用
    C#生成中文验证码
    C#导入Excel表
    IIS5、IIS6、IIS7的ASP.net 请求处理过程比较
    如何保证Session值不丢失
    C#抽象类与接口的区别
    C#实现DES加密解密
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8653038.html
Copyright © 2011-2022 走看看