zoukankan      html  css  js  c++  java
  • WC2006水管局长(加强)

    倒过来就变成了加边
    然后就直接LCT

    # include <stdio.h>
    # include <stdlib.h>
    # include <iostream>
    # include <algorithm>
    # include <string.h>
    # define IL inline
    # define RG register
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    
    IL ll Read(){
        RG char c = getchar(); RG ll x = 0, z = 1;
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
        return x * z;
    }
    
    const int MAXN(1020000);
    int n, m, Q, S[MAXN], ch[2][MAXN], fa[MAXN], mx[MAXN], rev[MAXN];
    int w[MAXN], from[MAXN], to[MAXN], id1[MAXN], vis[MAXN];
    int qx[MAXN], qy[MAXN], qk[MAXN], ans[MAXN], id2[MAXN], mark[MAXN];
    
    IL bool Son(RG int x){  return ch[1][fa[x]] == x;  }
    
    IL bool Isroot(RG int x){  return ch[0][fa[x]] != x && ch[1][fa[x]] != x;  }
    
    IL void Update(RG int x){
        mx[x] = x;
        if(w[mx[ch[0][x]]] > w[mx[x]]) mx[x] = mx[ch[0][x]];
        if(w[mx[ch[1][x]]] > w[mx[x]]) mx[x] = mx[ch[1][x]];
    }
    
    IL void Pushdown(RG int x){  if(!rev[x]) return; rev[x] = 0; rev[ch[0][x]] ^= 1; rev[ch[1][x]] ^= 1; swap(ch[0][x], ch[1][x]);  }
    
    IL void Rot(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){
        RG int top = 0; S[++top] = x;
        for(RG int y = x; !Isroot(y); y = fa[y]) S[++top] = fa[y];
        while(top) Pushdown(S[top--]);
        for(RG int y = fa[x]; !Isroot(x); Rot(x), y = fa[x])
            if(!Isroot(y)) Son(x) ^ Son(y) ? Rot(x) : Rot(y);
        Update(x);
    }
    
    IL void Access(RG int x){  for(RG int y = 0; x; y = x, x = fa[x]) Splay(x), ch[1][x] = y, Update(x);  }
    
    IL void Makeroot(RG int x){  Access(x); Splay(x); rev[x] ^= 1;  }
    
    IL int Findroot(RG int x){  Access(x); Splay(x); while(ch[0][x]) x = ch[0][x]; return x;  }
    
    IL void Split(RG int x, RG int y){  Makeroot(x); Access(y); Splay(y);  }
    
    IL void Link(RG int x, RG int y){  Makeroot(x); fa[x] = y;  }
    
    IL void Cut(RG int x, RG int y){  Split(x, y); fa[x] = ch[0][y] = 0;  }
    
    IL bool Cmp1(RG int x, RG int y){  return from[x] != from[y] ? from[x] < from[y] : to[x] < to[y];  }
    
    IL bool Cmp2(RG int x, RG int y){  return w[x] < w[y];  }
    
    IL bool Cmp3(RG int x, RG int y){  return qx[x] != qx[y] ? qx[x] < qx[y] : qy[x] < qy[y];  }
    
    int main(RG int argc, RG char* argv[]){
        n = Read(); m = Read(); Q = Read();
        for(RG int i = 1; i <= m; i++){
            from[i] = Read() + m, to[i] = Read() + m, w[i] = Read(), id1[i] = i;
            if(from[i] > to[i]) swap(from[i], to[i]);
        }
        sort(id1 + 1, id1 + m + 1, Cmp1);
        for(RG int i = 1; i <= Q; i++){
            qk[i] = Read(); qx[i] = Read() + m; qy[i] = Read() + m; id2[i] = i;
            if(qx[i] > qy[i]) swap(qx[i], qy[i]);
        }
        sort(id2 + 1, id2 + Q + 1, Cmp3);
        for(RG int i = 1, l = 1; i <= Q && l <= m; i++){
            if(qk[id2[i]] == 1) continue;
            while(l <= m && (qx[id2[i]] > from[id1[l]] || (qx[id2[i]] == from[id1[l]] && qy[id2[i]] > to[id1[l]]))) l++;
            if(l > m) break;
            if(qx[id2[i]] == from[id1[l]] && qy[id2[i]] == to[id1[l]]) vis[id1[l]] = 1, mark[id2[i]] = id1[l];
        }
        sort(id1 + 1, id1 + m + 1, Cmp2);
        for(RG int i = 1, t = 0; i <= m; i++){
            if(vis[id1[i]]) continue;
            if(Findroot(from[id1[i]]) == Findroot(to[id1[i]])) continue;
            Link(from[id1[i]], id1[i]); Link(to[id1[i]], id1[i]);
            t++; if(t == n - 1) break;
        }
        for(RG int i = Q; i >= 1; i--){
            if(qk[i] == 1) Split(qx[i], qy[i]), ans[i] = w[mx[qy[i]]];
            else{
                RG int x = from[mark[i]], y = to[mark[i]];
                if(Findroot(x) != Findroot(y)) Link(x, mark[i]), Link(y, mark[i]);
                else{
                    Split(x, y);
                    RG int ma = mx[y], xx = from[ma], yy = to[ma];
                    if(w[ma] > w[mark[i]]) Cut(xx, ma), Cut(yy, ma), Link(x, mark[i]), Link(y, mark[i]);
                }
            }
        }
        for(RG int i = 1; i <= Q; i++)
            if(qk[i] == 1) printf("%d
    ", ans[i]);
        return 0;
    }
  • 相关阅读:
    POJ 2240 Arbitrage spfa 判正环
    POJ 3259 Wormholes spfa 判负环
    POJ1680 Currency Exchange SPFA判正环
    HDU5649 DZY Loves Sorting 线段树
    HDU 5648 DZY Loves Math 暴力打表
    HDU5647 DZY Loves Connecting 树形DP
    CDOJ 1071 秋实大哥下棋 线段树
    HDU5046 Airport dancing links 重复覆盖+二分
    HDU 3335 Divisibility dancing links 重复覆盖
    FZU1686 神龙的难题 dancing links 重复覆盖
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8206381.html
Copyright © 2011-2022 走看看