BZOJ 3732: Network|动态树

来源:互联网 发布:如何不花钱做网络推广 编辑:程序博客网 时间:2024/06/04 23:36

看了po姐的blog..算了我也LCT水一发..
正常的做法
lct就是维护最小生成树,然后维护链上的最大值

#include<cstdio>  #include<cstdlib>  #include<cstring>  #include<cmath>  #include<queue>  #include<set>  #include<map>  #include<vector>  #include<algorithm>  #include<iostream>  #define N 303333  using namespace std;  int sc()  {      int i=0,f=1; char c=getchar();      while(c>'9'||c<'0'){if(c=='-')f=-1; c=getchar();}      while(c>='0'&&c<='9') i=i*10+c-'0',c=getchar();      return i*f;  }  bool rev[N];int fa[N],ch[N][2],mx[N],X[N],Y[N],v[N],st[N];int n,m,q;bool Root(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}void push_up(int x){    int l=ch[x][0],r=ch[x][1];    mx[x]=x;    if(l&&v[mx[l]]>v[mx[x]])mx[x]=mx[l];    if(r&&v[mx[r]]>v[mx[x]])mx[x]=mx[r];}void push_down(int x){    if(rev[x])    {        rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;        swap(ch[x][1],ch[x][0]);rev[x]=0;    }}void rotate(int x){    int y=fa[x],z=fa[y],l,r;    l=(ch[y][1]==x);r=l^1;    if(!Root(y))ch[z][ch[z][1]==y]=x;    fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;    ch[y][l]=ch[x][r];ch[x][r]=y;    push_up(y),push_up(x);}void splay(int x){    int top=1; st[1]=x;    for(int i=x;!Root(i);i=fa[i])st[++top]=fa[i];    while(top)push_down(st[top--]);    while(!Root(x))    {        int y=fa[x],z=fa[y];        if(!Root(y))            if(ch[z][0]==y^ch[y][0]==x) rotate(x);            else rotate(y);        rotate(x);    }}void access(int x){    for(int t=0;x;t=x,x=fa[x])        splay(x),ch[x][1]=t,push_up(x);}void make_root(int x){    access(x),splay(x),rev[x]^=1;}void link(int x,int y){    make_root(x),fa[x]=y;}void cut(int x,int y){    make_root(x),access(y),splay(y);    fa[x]=ch[y][0]=0; push_up(y);}   int find(int x){    access(x);    splay(x);    while(ch[x][0])x=ch[x][0],push_down(x);    return x;}int query(int x,int y){    make_root(x),access(y),splay(y);    return mx[y];}void solve(int x){    int a=X[x],b=Y[x];    int fx=find(a),fy=find(b);    if(fx==fy)    {        int f=query(a,b);        if(v[f]<=v[x])return;        cut(f,X[f]);cut(f,Y[f]);    }    link(x,a),link(x,b);}int main(){    n=sc();m=sc();q=sc();     for(int i=1;i<=n;i++)v[i]=-1,mx[i]=i;    for(int i=1;i<=m;i++)    {        X[n+i]=sc(),Y[n+i]=sc(),v[n+i]=sc();        solve(n+i);    }    for(int i=1;i<=q;i++)    {        int x=sc(),y=sc();        printf("%d\n",v[query(x,y)]);    }    return 0;}
0 0
原创粉丝点击