记录编号 478872 评测结果 AAAAAAAAAAAAAAA
题目名称 [WC 2006]水管局长数据加强版 最终得分 100
用户昵称 GravatarCooook 是否通过 通过
代码语言 C++ 运行时间 6.197 s
提交时间 2017-12-14 21:13:22 内存使用 99.50 MiB
显示代码纯文本
#pragma GCC optimize("O3")
#include <bits/stdc++.h>

#define Debug printf("%d\n",__LINE__)
#define id(_) (_-null)
#define fi first
#define se second
#define mk std::make_pair

typedef std::pair<int,int> pii;

const int MAXN = 100005,MAXM = 2e6+5;
int n,m,Q,val[MAXM>>1],u[MAXM>>1],v[MAXM>>1],cnt,Ans[MAXM>>1],Query_time;


template <typename _t>
inline _t read(){
    _t x = 0, f = 1;
    char ch = getchar();
    for (; ch < '0' | ch > '9'; ch = getchar()) if (ch == '-') f = -f;
    for (; ch >= '0' & ch <= '9'; ch = getchar()) x = x * 10 + (ch ^ 48);
    return x * f;
}

struct edge{int u,v,w;}a[MAXM>>1];
struct Operation{int op,x,y;}op[(int)1e6+5];
struct node{
    node *ch[2],*f;
    int mx,val,tag,id,pos;
    inline void Maintain();
    inline void Push_down();
    inline void rev();
    inline void rotate();
    inline void Splay();
    inline bool dir();
    inline bool isrt();
}null[MAXM];

inline bool node::dir(){
    return f -> ch[1] == this;
}

inline bool node::isrt(){
    return f -> ch[0] != this && f -> ch[1] != this;
}

inline void node::rev(){
    if (this == null) return;
    std::swap(ch[0],ch[1]), tag ^= 1;
}

inline void node::rotate(){
    node *fa = f, *pa = fa -> f; int d = dir();
    if (!fa -> isrt()) pa -> ch[fa -> dir()] = this;
    if ((fa -> ch[d] = ch[d ^ 1]) != null) ch[d ^ 1] -> f = fa;
    fa -> f = this; this -> f = pa; ch[d ^ 1] = fa;
    fa -> Maintain(); Maintain();
}

inline void node::Splay(){
    Push_down();
    for (node *t = f; !isrt(); rotate(), t = f) 
        if (!t -> isrt()){
            t -> f -> Push_down(), t -> Push_down(), Push_down();
            if (t -> dir() == dir()) t -> rotate();
            else rotate();
        }
        else t -> Push_down(), Push_down();
}

inline void node::Push_down(){
    if (this == null) return;
    if (tag) tag ^= 1, ch[0] -> rev(), ch[1] -> rev();
}

inline void node::Maintain(){
    if (this == null) return;
    mx = std::max(std::max(ch[0] -> mx,ch[1] -> mx),val);
    if (mx == ch[0] -> mx) pos = ch[0] -> pos;
    else if (mx == ch[1] -> mx) pos = ch[1] -> pos;
    else if (mx == val) pos = id;
}

inline void Access(node *x){
    node *y = null;
    while (x != null)
        x -> Splay(),
        x -> ch[1] = y,
        x -> Maintain(),
        y = x, x = x -> f;
}

inline void Make_root(node *x){
    Access(x); x -> Splay(); x -> rev();
}

inline void Link(node *x,node *y){
    Make_root(x); x -> Splay(); x -> f = y;
}

inline void Cut(node *x,node *y){
    Make_root(x); Access(y); x -> Splay();
    x -> ch[1] = y -> f = null;
}

inline node* find(node *x){
    Access(x); x -> Splay(); x -> Push_down();
    while (x -> ch[0] != null)
        x = x -> ch[0], x -> Push_down();
    return x;
}

inline int Query(node *x,node *y){
    Make_root(x);
    Access(y);
    y -> Splay();
    return y -> pos;
}

inline void Add_Edge(node *x,node *y,node *z,int w){
    if (find(x) != find(y))
        return Link(x,z), Link(y,z), void();
    else {
        int id = Query(x,y);
        if (w < val[id-n]) Cut(&null[a[id-n].u],&null[id]),Cut(&null[a[id-n].v],&null[id]),Link(x,z),Link(y,z);
    }
}

std::map<pii,int> ma,Del;

int main(){
    freopen("tube_strong.in","r",stdin);
    freopen("tube_strong.out","w",stdout);
    n = read<int>(), m = read<int>(), Q = read<int>();
    for (int i = 0; i <= n + m; i++)
        null[i].ch[0] = null[i].ch[1] = null[i].f = null,
        null[i].tag = 0, null[i].id = i, null[i].mx = 0, null[i].pos = i;
    for (int i = 1; i <= m; i++){
        a[i].u = read<int>(),a[i].v = read<int>(),a[i].w = read<int>();
        null[i+n].mx = null[i+n].val = a[i].w; val[i] = a[i].w; 
        if (a[i].u > a[i].v) std::swap(a[i].u,a[i].v);
        ma[mk(a[i].u,a[i].v)] = i;
    }
    for (int i = 1; i <= Q; ++i){
        op[i].op = read<int>(),op[i].x = read<int>(), op[i].y = read<int>();
        if (op[i].x > op[i].y) std::swap(op[i].x,op[i].y);
        if (op[i].op == 2) Del[mk(op[i].x,op[i].y)] = ma[mk(op[i].x,op[i].y)], ma.erase(mk(op[i].x,op[i].y));
    }
    for (int i = 1; i <= m; i++)
        if (ma.count(mk(a[i].u,a[i].v)))
            Add_Edge(&null[a[i].u],&null[a[i].v],&null[n+i],a[i].w);
    for (int i = Q; i; --i){
        if (op[i].op == 1)
            Ans[++Query_time] = val[Query(&null[op[i].x],&null[op[i].y]) - n];
        else Add_Edge(&null[op[i].x],&null[op[i].y],&null[Del[mk(op[i].x,op[i].y)]+n],val[Del[mk(op[i].x,op[i].y)]]);
    }
    for (int i = Query_time; i; --i) printf("%d\n",Ans[i]);
    return 0;
}