[UOJ274][BZOJ4736][清华集训2016]温暖会指引我们前行(边权LCT)

题目传送门

分析

  这题实际上如果你把他的温度看做边权的话,那么实际上这题就是要你动态维护最大生成树,这个东西用边权LCT做就行了。至于边权LCT是什么,可以自行百度学习学习啦(光速逃)..

Code

#pragma GCC optimize(3,"Ofast","inline")
#include
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
/*================Header Template==============*/
const int maxn=400005,inf=0x3f3f3f3f;
struct Edge {
    int u,v;
    Edge(int u=0,int v=0):u(u),v(v){}
}edges[maxn];
namespace LCT {
    struct Node {
        int fa,dis,val,rev,len,Min,ch[2];
        Node(int fa=0,int dis=0,int val=inf,int rev=0,int len=0,int Min=inf):fa(fa),dis(dis),val(val),rev(rev),len(len),Min(Min){ch[0]=ch[1]=0;}
        inline int& operator [] (int y) {
            return this->ch[y];
        }
    }T[maxn];
    inline void Reverse(int x) {
        swap(T[x][0],T[x][1]);
        T[x].rev^=1;
    }
    inline void Pushup(int x) {
        T[x].len=T[x].dis,T[x].Min=T[x].val;
        if(T[x][0])
            T[x].len+=T[T[x][0]].len,T[x].Min=min(T[x].Min,T[T[x][0]].Min);
        if(T[x][1])
            T[x].len+=T[T[x][1]].len,T[x].Min=min(T[x].Min,T[T[x][1]].Min);
    }
    inline void Pushdown(int x) {
        if(T[x].rev) {
            if(T[x][0])
                Reverse(T[x][0]);
            if(T[x][1])
                Reverse(T[x][1]);
            T[x].rev^=1;
        }
    }
    inline bool Isroot(int x) {
        return T[T[x].fa][0]!=x&&T[T[x].fa][1]!=x;
    }
    inline void Pushtag(int x) {
        if(!Isroot(x))
            Pushtag(T[x].fa);
        Pushdown(x);
    }
    inline int Isright(int x) {
        return T[T[x].fa][1]==x;
    }
    inline void Rotate(int x) {
        int y=T[x].fa,z=T[y].fa,r=Isright(x),l=r^1;
        if(!Isroot(y))
            T[z][Isright(y)]=x;
        T[x].fa=z,T[y].fa=x;
        T[T[x][l]].fa=y;
        T[y][r]=T[x][l];
        T[x][l]=y;
        Pushup(y),Pushup(x);
    }
    inline void Splay(int x) {
        Pushtag(x);
        while(!Isroot(x)) {
            int y=T[x].fa;
            if(!Isroot(y)) {
                if(Isright(x)==Isright(y))
                    Rotate(y);
                else
                    Rotate(x);
            }
            Rotate(x);
        }
    }
    inline void Access(int x) {
        int t=0;
        for(;x;t=x,x=T[x].fa)
            Splay(x),T[x][1]=t,Pushup(x);
    }
    inline void Makeroot(int x) {
        Access(x),Splay(x),Reverse(x);
    }
    inline void Link(int x,int y) {
        Makeroot(x),Makeroot(y),T[x].fa=y;
    }
    inline void Cut(int x,int y) {
        Makeroot(x),Access(y),Splay(y),T[y][0]=T[x].fa=0,Pushup(y);
    }
    inline int Getfa(int x) {
        while(T[x].fa)
            x=T[x].fa;
        return x;
    }
}
using namespace LCT;
int n,q,ty,id,u,v,t,l;
char s[10];
unordered_map<int,int>Bel;
inline void Addedge(int id,int u,int v,int t,int l) {
    edges[id]=Edge(u,v);
    Bel[t]=id;
    int x=id+n;
    T[x].dis=l,T[x].val=t;
    Pushup(x),Link(x,u),Link(x,v);
}
inline void Deledge(int id) {
    int u=edges[id].u,v=edges[id].v,x=id+n;
    Cut(x,u),Cut(x,v);
}
int main() {
    read(n),read(q);
    while(q--) {
        scanf("%s",s);
        if(s[0]=='f') {
            read(id),read(u),read(v),read(t),read(l);
            id++,u++,v++;
            Makeroot(u),Makeroot(v);
            if(Getfa(u)!=Getfa(v))
                Addedge(id,u,v,t,l);
            else {
                Makeroot(u),Access(v),Splay(v);
                int Min=T[v].Min;
                if(t>Min) {
                    Deledge(Bel[Min]);
                    Addedge(id,u,v,t,l);
                }
            }
        }
        if(s[0]=='m') {
            read(u),read(v),++u,++v;
            Makeroot(u),Makeroot(v);
            if(Getfa(u)!=Getfa(v))
                puts("-1");
            else {
                Makeroot(u),Access(v),Splay(v);
                printf("%d\n",T[v].len);
            }
        }
        if(s[0]=='c') {
            read(id),read(l),++id;
            int x=id+n;
            Makeroot(x),T[x].dis=l,Pushup(x);
        }
    }
}

你可能感兴趣的:(LCT)