zoukankan      html  css  js  c++  java
  • UOJ#274. 【清华集训2016】温暖会指引我们前行

    题面

    UOJ

    题解

    (LCT)板子题

    维护一个最大生成树即可

    Code

    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    
    using namespace std;
    template<class T> inline void read(T &x) {
    	x = 0; RG char c = getchar(); bool f = 0;
    	while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
    	while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
    	x = f ? -x : x;
    	return ;
    }
    template<class T> inline void write(T x) {
    	if (!x) {putchar(48);return ;}
    	if (x < 0) x = -x, putchar('-');
    	int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
    	for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
    }
    const int N = 600010;
    int n, m, v;
    int Min[N], pos[N], ch[N][2], fa[N], S[N], top, val[N], len[N], w[N];
    bool rev[N];
    void pushup(int x) {
    	Min[x] = val[x]; pos[x] = x;
    	if (ch[x][0] && Min[ch[x][0]] < Min[x]) Min[x] = Min[ch[x][0]], pos[x] = pos[ch[x][0]];
    	if (ch[x][1] && Min[ch[x][1]] < Min[x]) Min[x] = Min[ch[x][1]], pos[x] = pos[ch[x][1]];
    	w[x] = w[ch[x][0]] + w[ch[x][1]] + len[x];
    }
    void putrev(int x) {
    	swap(ch[x][0], ch[x][1]);
    	rev[x] ^= 1;
    }
    void pushdown(int x) {
    	if (rev[x]) {
    		if (ch[x][0]) putrev(ch[x][0]);
    		if (ch[x][1]) putrev(ch[x][1]);
    		rev[x] = 0;
    	}
    }
    bool isroot(int x) {
    	return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
    }
    #define get(x) (ch[fa[x]][1] == x)
    void rotate(int x) {
    	int y = fa[x], z = fa[y], k = get(x);
    	if (!isroot(y)) ch[z][get(y)] = x;
    	fa[x] = z;
    	ch[y][k] = ch[x][k ^ 1]; fa[ch[x][k ^ 1]] = y;
    	ch[x][k ^ 1] = y; fa[y] = x;
    	pushup(y);
    }
    void splay(int x) {
    	S[top = 1] = x;
    	for (int i = x; !isroot(i); i = fa[i]) S[++top] = fa[i];
    	for (int i = top; i; i--) pushdown(S[i]);
    	while (!isroot(x)) {
    		int y = fa[x];
    		if (!isroot(y))
    			(get(x) ^ get(y)) ? rotate(x) : rotate(y);
    		rotate(x);
    	}
    	pushup(x);
    }
    void access(int x) { for (int y = 0; x; y = x, x = fa[x]) splay(x), ch[x][1] = y, pushup(x); }
    void makeroot(int x) { access(x); splay(x); putrev(x); }
    void link(int x, int y) { makeroot(x); fa[x] = y; }
    void split(int x, int y) { makeroot(x); access(y); splay(y); }
    void cut(int x, int y) { split(x, y); fa[x] = ch[y][0] = 0; pushup(y); }
    char s[10];
    int Fa[N], E[N][2];
    int find(int x) {
    	return x == Fa[x] ? x : Fa[x] = find(Fa[x]);
    }
    int main() {
    	//freopen(".in", "r", stdin);
    	//freopen(".out", "w", stdout);
    	read(n), read(m);
    	for (int i = 1; i <= n; i++) val[i] = 2147483647, Fa[i] = i; 
    	while (m--) {
    		scanf("%s", s);
    		if (s[0] == 'f') {
    			int id, u, v;
    			read(id), read(u), read(v);
    			id += n + 1; u++; v++;
    			E[id][0] = u; E[id][1] = v;
    			read(val[id]), read(len[id]);
    			if (find(u) != find(v))
    				link(u, id), link(id, v);			
    			else {
    				split(u, v);
    				if (Min[v] < val[id]) {
    					int k = pos[v];
    					cut(E[k][0], k), cut(k, E[k][1]);
    					link(u, id), link(id, v);
    				}
    			}
    			Fa[find(v)] = find(u);
    		}
    		else if (s[0] == 'm') {
    			int u, v;
    			read(u), read(v);
    			u++; v++;
    			if (find(u) != find(v)) {
    				puts("-1");
    				continue;
    			}
    			split(u, v);
    			printf("%d
    ", w[v]);
    		}
    		else {
    			int id, l;
    			read(id), read(l);
    			id += n + 1;
    			len[id] = l;
    			splay(id);
    			pushup(id);
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    第一次作业 —— 【作业7】问卷调查
    讲座观后感
    学习进度表(随缘更新)
    数据结构与算法思维导图
    作业七问卷调查
    《创新者的逆袭,用第一性原理做颠覆式创新》读后感
    结对项目--四则运算生成器(Java) 刘彦享+龙俊健
    个人项目---WordCount实现(Java)
    自我介绍+软工五问
    简洁又快速地处理集合——Java8 Stream(下)
  • 原文地址:https://www.cnblogs.com/zzy2005/p/10603898.html
Copyright © 2011-2022 走看看