• HDU5002 Tree(LCT)


    今天做了一道LCT模板题之后忽然间好像记起来LCT的模板怎么用了,于是就把上次网络赛的一道LCT补一下。典型的删边,加边操作,还有路径加和路径set为一个数。维护的是路径第二大以及它有多少个,后来想想其实确实是挺好写的,就是维护最大值以及次大值,然后upd的时候把儿子合并回去就好了,当时觉得不会做实在是想太多了。

    #pragma warning(disable:4996)
    #include <iostream>
    #include <cstring>
    #include <string>
    #include <cstdio>
    #include <vector>
    #include <algorithm>
    #include <map>
    using namespace std;
    
    #define ll long long
    #define maxn 200000
    #define INF 0x3f3f3f3f
    #define INP INF+1
    #define MP make_pair
    
    void merge(int mxx[2], int nxx[2], int pval, int pnum)
    {
    	if (pval>mxx[0]){
    		mxx[1] = mxx[0]; nxx[1] = nxx[0];
    		mxx[0] = pval; nxx[0] = pnum;
    	}
    	else if (pval == mxx[0]){
    		nxx[0] += pnum;
    	}
    	else if (pval>mxx[1]){
    		mxx[1] = pval; nxx[1] = pnum;
    	}
    	else if(pval==mxx[1]){
    		nxx[1] += pnum;
    	}
    }
    
    
    struct Node
    {
    	Node *p, *ch[2];
    	bool rev;
    	int val;
    	int mx[2], num[2];
    	int add, cov;
    	int size;
    	bool isRoot;
    	Node *fa;
    	Node(){
    		val = 0; rev = 0;
    		add = 0; cov = INP;
    		mx[0] = mx[1] = -INF;
    		num[0] = num[1] = 0;
    		size = 0;
    	}
    	void setc(Node *c, int d){
    		ch[d] = c;
    		c->p = this;
    	}
    	bool d(){
    		return p->ch[1] == this;
    	}
    	void upd(){
    		size = ch[0]->size + ch[1]->size + 1;
    		mx[0] = ch[0]->mx[0]; num[0] = ch[0]->num[0];
    		mx[1] = ch[0]->mx[1]; num[1] = ch[0]->num[1];
    		merge(mx, num, val, 1);
    		merge(mx, num, ch[1]->mx[0], ch[1]->num[0]);
    		merge(mx, num, ch[1]->mx[1], ch[1]->num[1]);
    	}
    	void revIt(){
    		rev ^= 1;
    		swap(ch[0], ch[1]);
    	}
    	void addIt(int vx){
    		add += vx;
    		val += vx;
    		if (mx[0] != -INF) mx[0] += vx;
    		if (mx[1] != -INF) mx[1] += vx;
    	}
    	void setIt(int vx){
    		add = 0;
    		cov = vx;
    		val = vx;
    		mx[0] = vx; num[0] = size;
    		mx[1] = -INF; num[1] = 0;
    	}
    	void relax();
    	void setRoot(Node *f);
    }Tnull, *null = &Tnull;
    
    void Node::setRoot(Node *f){
    	fa = f;
    	isRoot = true;
    	p = null;
    }
    
    void Node::relax(){
    	if (cov != INP){
    		for (int i = 0; i<2; ++i){
    			if (ch[i] != null) ch[i]->setIt(cov);
    		}
    		cov = INP;
    	}
    	if (add != 0){
    		for (int i = 0; i < 2; i++){
    			if (ch[i] != null) ch[i]->addIt(add);
    		}
    		add = 0;
    	}
    	if (rev){
    		for (int i = 0; i < 2; i++){
    			if (ch[i] != null) ch[i]->revIt();
    		}
    		rev = 0;
    	}
    }
    
    Node mem[maxn], *C = mem;
    
    Node *make(int v){
        C->size=1;
    	C->val = v;
    	C->rev = 0; C->add = 0;
    	C->cov = INP;
    	C->mx[0] = v; C->num[0] = 1;
    	C->mx[1] = -INF; C->num[1] = 0;
    	C->ch[0] = C->ch[1] = null; C->isRoot = true;
    	C->p = null;
    	C->fa = null;
    	return C++;
    }
    
    void rot(Node *t){
    	Node *p = t->p;
    	p->relax();
    	t->relax();
    	bool d = t->d();
    	p->p->setc(t, p->d());
    	p->setc(t->ch[!d], d);
    	t->setc(p, !d);
    	p->upd();
    	if (p->isRoot){
    		p->isRoot = false;
    		t->isRoot = true;
    		t->fa = p->fa;
    	}
    }
    
    void pushTo(Node*t) {
    	static Node*stk[maxn]; int top = 0;
    	while (t != null) {
    		stk[top++] = t;
    		t = t->p;
    	}
    	for (int i = top - 1; i >= 0; --i) stk[i]->relax();
    }
    
    void splay(Node*u, Node*f = null) {
    	pushTo(u);
    	while (u->p != f) {
    		if (u->p->p == f)
    			rot(u);
    		else
    			u->d() == u->p->d() ? (rot(u->p), rot(u)) : (rot(u), rot(u));
    	}
    	u->upd();
    }
    
    Node *v[maxn];
    vector<int> E[maxn];
    int n, nQ;
    
    int que[maxn], fa[maxn], qh = 0, qt = 0;
    int wht[maxn];
    
    void bfs()
    {
    	qh = qt = 0;
    	que[qt++] = 1;
    	fa[1] = -1;
    	while (qh < qt){
    		int u = que[qh++];
    		for (int i = 0; i < E[u].size(); i++){
    			int e = E[u][i];
    			if (e != fa[u]){
    				fa[e] = u;
    				v[e]->fa = v[u];
    				que[qt++] = e;
    			}
    		}
    	}
    }
    
    Node *expose(Node *u)
    {
    	Node *v;
    	for (v = null; u != null; v = u, u = u->fa){
    		splay(u);
    		u->ch[1]->setRoot(u);
    		u->setc(v, 1);
    		v->fa = u;
    	}
    	return v;
    }
    
    void makeRoot(Node *u)
    {
    	expose(u);
    	splay(u);
    	u->revIt();
    }
    
    void addEdge(Node *u, Node *v)
    {
    	makeRoot(v);
    	v->fa = u;
    }
    
    void delEdge(Node *u, Node *v)
    {
    	makeRoot(u);
    	expose(v); splay(u); u->setc(null, 1); u->upd();
    	v->setRoot(null);
    }
    
    void addPath(Node *u, Node *v, int ax)
    {
    	makeRoot(u);
    	expose(v);
    	splay(v);
    	v->addIt(ax);
    }
    
    void setPath(Node *u, Node *v, int ax)
    {
    	makeRoot(u);
    	expose(v);
    	splay(v);
    	v->setIt(ax);
    }
    
    pair<int, int> queryPath(Node *u, Node *v){
    	makeRoot(u);
    	expose(v);
    	splay(v);
    	return MP(v->mx[1], v->num[1]);
    }
    
    Node *find_root(Node *u)
    {
    	expose(u); splay(u);
    	while (u->ch[0] != null){
    		u = u->ch[0];
    	}
    	splay(u); return u;
    }
    
    int main()
    {
    	int T; cin >> T;int ca=0;
    	while (T--)
    	{
    		C = mem;
    		scanf("%d%d", &n, &nQ);
    		for (int i = 1; i <= n; i++){
    			scanf("%d", wht + i);
    			v[i] = make(wht[i]);
    		}
    		for (int i = 0; i <= n; i++) E[i].clear();
    		int ui, vi;
    		for (int i = 0; i < n - 1; i++){
    			scanf("%d%d", &ui, &vi);
    			E[ui].push_back(vi); E[vi].push_back(ui);
    		}
    		bfs();
    		int cmd, xi, yi, ai, bi;
    		Node *nx, *ny, *na, *nb;
    		printf("Case #%d:
    ",++ca);
    		while (nQ--){
    			scanf("%d", &cmd);
    			if (cmd == 1) scanf("%d%d%d%d", &xi, &yi, &ai, &bi);
    			else if (cmd == 2 || cmd == 3) scanf("%d%d%d", &ai, &bi, &xi);
    			else scanf("%d%d", &ai, &bi);
    
    			if (cmd == 1){
    				nx = v[xi]; ny = v[yi];
    				na = v[ai]; nb = v[bi];
    				delEdge(nx, ny);
    				addEdge(na, nb);
    			}
    			else if (cmd == 2){
    				nx = v[ai]; ny = v[bi];
    				setPath(nx, ny, xi);
    			}
    			else if (cmd == 3){
    				nx = v[ai]; ny = v[bi];
    				addPath(nx, ny, xi);
    			}
    			else{
    				nx = v[ai]; ny = v[bi];
    				pair<int, int> ans = queryPath(nx, ny);
    				if (ans.first <= -INF) printf("ALL SAME
    ");
    				else printf("%d %d
    ", ans.first, ans.second);
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    idea设置全局ignore
    win 2012 安装mysql 5.7.20 及报错 This application requires Visual Studio 2013 Redistributable. Please ins
    win 2012 安装mysql 5.7.20 及报错 This application requires Visual Studio 2013 Redistr
    kafka 删除 topic
    java编译中出现了Exception in thread “main" java.lang.UnsupportedClassVersionError
    Centos中使用yum安装java时,没有jps的问题的解决
    Spring 整合Junit
    Spring纯注解配置
    Spring 基于注解的 IOC 配置
    打印java系统的信息
  • 原文地址:https://www.cnblogs.com/chanme/p/3997481.html
Copyright © 2020-2023  润新知