zoukankan      html  css  js  c++  java
  • 一堆LCT板子

    搞了一上午LCT,真是累死了……

    以前总觉得LCT高大上不好学不好打,今天打了几遍感觉还可以嘛= =反正现在的水平应付不太难的LCT题也够用了,就这样好了,接下来专心搞网络流。

    话说以前一直YY不出来LCT怎么维护边权,多谢sxysxy告诉我要添虚点来把边权转化为点权,感激不尽……

    言归正传。

     

    [国家集训队2012]tree(伍一鸣)

    LCT模板题嘛……

    区间乘和区间加一遍写对,感觉费了好多rp……

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<vector>
      5 #define isroot(x) ((x)->p==null||((x)->p->ch[0]!=(x)&&(x)->p->ch[1]!=(x)))
      6 #define dir(x) ((x)==(x)->p->ch[1])
      7 using namespace std;
      8 typedef unsigned uint;
      9 const int maxn=100010;
     10 const uint M=51061u;
     11 struct node{
     12     uint data,sm,a,b;
     13     int size;
     14     node *ch[2],*p;
     15     bool rev;
     16     node(uint d=0u):data(d),sm(d),a(1u),b(0u),size(1),rev(false){}
     17     void add(uint d){
     18         sm+=(uint)size%M*d%M;sm%=M;
     19         data+=d;data%=M;
     20         b+=d;b%=M;
     21     }
     22     void mul(uint d){
     23         sm*=d;sm%=M;
     24         data*=d;data%=M;
     25         b*=d;b%=M;
     26         a*=d;a%=M;
     27     }
     28     void pushdown(){
     29         if(rev){
     30             ch[0]->rev^=true;
     31             ch[1]->rev^=true;
     32             swap(ch[0],ch[1]);
     33             rev=false;
     34         }
     35         if(a!=1){
     36             ch[0]->mul(a);
     37             ch[1]->mul(a);
     38             a=1u;
     39         }
     40         if(b){
     41             ch[0]->add(b);
     42             ch[1]->add(b);
     43             b=0u;
     44         }
     45     }
     46     void refresh(){
     47         size=ch[0]->size+ch[1]->size+1;
     48         sm=ch[0]->sm+ch[1]->sm;sm%=M;sm+=data;sm%=M;
     49     }
     50 }nodes[maxn],*null=nodes;
     51 void dfs(int);
     52 void add(node*,node*,uint);
     53 void mul(node*,node*,uint);
     54 uint qsum(node*,node*);
     55 node *access(node*);
     56 void makeroot(node*);
     57 void link(node*,node*);
     58 void cut(node*,node*);
     59 void splay(node*);
     60 void rot(node*,int);
     61 vector<int>G[maxn];
     62 int n,m,prt[maxn]={0},x,y;
     63 uint d;
     64 char c;
     65 int main(){
     66     freopen("nt2012_wym_tree.in","r",stdin);
     67     freopen("nt2012_wym_tree.out","w",stdout);
     68     null->ch[0]=null->ch[1]=null->p=null;
     69     null->size=0;
     70     scanf("%d%d",&n,&m);
     71     for(int i=1;i<n;i++){
     72         scanf("%d%d",&x,&y);
     73         G[x].push_back(y);
     74         G[y].push_back(x);
     75     }
     76     dfs(1);
     77     for(int i=1;i<=n;i++){
     78         nodes[i]=node(1);
     79         nodes[i].ch[0]=nodes[i].ch[1]=null;
     80         nodes[i].p=nodes+prt[i];
     81     }
     82     while(m--){
     83         scanf(" %c%d%d",&c,&x,&y);
     84         if(c=='+'){
     85             scanf("%u",&d);
     86             add(nodes+x,nodes+y,d);
     87         }
     88         else if(c=='-'){
     89             cut(nodes+x,nodes+y);
     90             scanf("%d%d",&x,&y);
     91             link(nodes+x,nodes+y);
     92         }
     93         else if(c=='*'){
     94             scanf("%u",&d);
     95             mul(nodes+x,nodes+y,d);
     96         }
     97         else if(c=='/')printf("%u
    ",qsum(nodes+x,nodes+y));
     98     }
     99     return 0;
    100 }
    101 void dfs(int x){
    102     for(int i=0;i<(int)G[x].size();i++)if(G[x][i]!=prt[x]){
    103         prt[G[x][i]]=x;
    104         dfs(G[x][i]);
    105     }
    106 }
    107 void add(node *x,node *y,uint d){
    108     makeroot(x);
    109     access(y)->add(d);
    110 }
    111 void mul(node *x,node *y,uint d){
    112     makeroot(x);
    113     access(y)->mul(d);
    114 }
    115 uint qsum(node *x,node *y){
    116     makeroot(x);
    117     return access(y)->sm;
    118 }
    119 node *access(node *x){
    120     node *y=null;
    121     while(x!=null){
    122         splay(x);
    123         x->ch[1]=y;
    124         (y=x)->refresh();
    125         x=x->p;
    126     }
    127     return y;
    128 }
    129 void makeroot(node *x){
    130     access(x);
    131     splay(x);
    132     x->rev^=true;
    133 }
    134 void link(node *x,node *y){
    135     makeroot(x);
    136     x->p=y;
    137 }
    138 void cut(node *x,node *y){
    139     makeroot(x);
    140     access(y);
    141     splay(y);
    142     x->p=null;
    143     y->ch[0]=null;
    144     y->refresh();
    145 }
    146 void splay(node *x){
    147     x->pushdown();
    148     while(!isroot(x)){
    149         if(!isroot(x->p))x->p->p->pushdown();
    150         x->p->pushdown();
    151         x->pushdown();
    152         if(isroot(x->p)){
    153             rot(x->p,dir(x)^1);
    154             break;
    155         }
    156         if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
    157         else rot(x->p,dir(x)^1);
    158         rot(x->p,dir(x)^1);
    159     }
    160 }
    161 void rot(node *x,int d){
    162     node *y=x->ch[d^1];
    163     x->ch[d^1]=y->ch[d];
    164     if(y->ch[d]!=null)y->ch[d]->p=x;
    165     y->p=x->p;
    166     if(!isroot(x))x->p->ch[dir(x)]=y;
    167     y->ch[d]=x;
    168     x->p=y;
    169     x->refresh();
    170     y->refresh();
    171 }
    View Code

     

    [Sdoi2008]Cave 洞穴勘测

    也是LCT维护森林连通性的模板题。

    话说一开始读错题了,以为是一般图,就写了一发分治并查集,然后发现LCT又好写又跑得快……

    分治并查集的代码长度亮了……

    分治并查集:

    /**************************************************************
        Problem: 2049
        User: hzoier
        Language: C++
        Result: Accepted
        Time:4988 ms
        Memory:58572 kb
    ****************************************************************/
     
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    using namespace std;
    const int maxn=10010,maxm=200010;
    inline int randint(){
        static int a=1213,b=78181,c=49189487,x=987654321,p=998244353;
        x=a*x*x+b*x+c;x%=p;x+=p;
        return x%=p;
    }
    void addedge(int,int,int);
    void addquery(int,int,int);
    void solve(int,int,int);
    int findroot(int);
    void mergeset(int,int,vector<int>&);
    int prt[maxn];
    map<pair<int,int>,int>mp;
    vector<int>u[maxm<<2],v[maxm<<2],stk[maxm<<2];
    int qu[maxm<<2]={0},qv[maxm<<2];
    int n,m,x,y,s,t;
    char c[15];
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)prt[i]=i;
        for(int i=1;i<=m;i++){
            scanf("%s%d%d",c,&x,&y);
            if(x>y)swap(x,y);
            if(*c=='C'){
                if(!mp.count(make_pair(x,y)))mp[make_pair(x,y)]=i;
            }
            else if(*c=='D'){
                s=mp[make_pair(x,y)];
                t=i;
                addedge(1,m,1);
                mp.erase(make_pair(x,y));
            }
            else{
                t=i;
                addquery(1,m,1);
            }
        }
        t=m;
        for(map<pair<int,int>,int>::iterator it=mp.begin();it!=mp.end();it++){
            x=it->first.first;
            y=it->first.second;
            s=it->second;
            addedge(1,m,1);
        }
        solve(1,m,1);
        return 0;
    }
    void addedge(int l,int r,int rt){
        if(s<=l&&t>=r){
            u[rt].push_back(x);
            v[rt].push_back(y);
            return;
        }
        int mid=(l+r)>>1;
        if(s<=mid)addedge(l,mid,rt<<1);
        if(t>mid)addedge(mid+1,r,rt<<1|1);
    }
    void addquery(int l,int r,int rt){
        qu[rt]|=x;
        if(l==r){
            qv[rt]=y;
            return;
        }
        int mid=(l+r)>>1;
        if(t<=mid)addquery(l,mid,rt<<1);
        else addquery(mid+1,r,rt<<1|1);
    }
    void solve(int l,int r,int rt){
        if(!qu[rt])return;
        for(int i=0;i<(int)u[rt].size();i++)mergeset(u[rt][i],v[rt][i],stk[rt]);
        if(l==r)printf(findroot(qu[rt])==findroot(qv[rt])?"Yes
    ":"No
    ");
        else{
            int mid=(l+r)>>1;
            solve(l,mid,rt<<1);
            solve(mid+1,r,rt<<1|1);
        }
        if(!stk[rt].empty())for(int i=(int)stk[rt].size()-1;i>=0;i--)prt[stk[rt][i]]=stk[rt][i];
    }
    void mergeset(int x,int y,vector<int>&a){
        x=findroot(x);y=findroot(y);
        if(x==y)return;
        if(randint()&1)swap(x,y);
        prt[x]=y;
        a.push_back(x);
    }
    int findroot(int x){
        while(prt[x]!=x)x=prt[x];
        return x;
    }
    View Code

    LCT:

      1 /**************************************************************
      2     Problem: 2049
      3     User: hzoier
      4     Language: C++
      5     Result: Accepted
      6     Time:1656 ms
      7     Memory:976 kb
      8 ****************************************************************/
      9  
     10 #include<cstdio>
     11 #include<cstring>
     12 #include<algorithm>
     13 #define isroot(x) ((x)->p==null||((x)->p->ch[0]!=(x)&&(x)->p->ch[1]!=(x)))
     14 #define dir(x) ((int)((x)==(x)->p->ch[1]))
     15 using namespace std;
     16 const int maxn=10010;
     17 struct node{
     18     bool rev;
     19     node *ch[2],*p;
     20     node():rev(false){}
     21     void pushdown(){
     22         if(!rev)return;
     23         ch[0]->rev^=true;
     24         ch[1]->rev^=true;
     25         swap(ch[0],ch[1]);
     26         rev=false;
     27     }
     28 }nodes[maxn],*null=nodes;
     29 node *access(node*);
     30 void makeroot(node*);
     31 void link(node*,node*);
     32 void cut(node*,node*);
     33 node *findroot(node*);
     34 void splay(node*);
     35 void rot(node*,int);
     36 int n,m,x,y;
     37 char c[15];
     38 int main(){
     39     null->ch[0]=null->ch[1]=null->p=null;
     40     scanf("%d%d",&n,&m);
     41     for(int i=1;i<=n;i++)nodes[i].ch[0]=nodes[i].ch[1]=nodes[i].p=null;
     42     while(m--){
     43         scanf("%s%d%d",c,&x,&y);
     44         if(*c=='C')link(nodes+x,nodes+y);
     45         else if(*c=='D')cut(nodes+x,nodes+y);
     46         else printf(findroot(nodes+x)==findroot(nodes+y)?"Yes
    ":"No
    ");
     47     }
     48     return 0;
     49 }
     50 node *access(node *x){
     51     node *y=null;
     52     while(x!=null){
     53         splay(x);
     54         x->ch[1]=y;
     55         y=x;
     56         x=x->p;
     57     }
     58     return y;
     59 }
     60 void makeroot(node *x){
     61     access(x);
     62     splay(x);
     63     x->rev^=true;
     64 }
     65 void link(node *x,node *y){
     66     makeroot(x);
     67     x->p=y;
     68 }
     69 void cut(node *x,node *y){
     70     makeroot(x);
     71     access(y);
     72     splay(y);
     73     y->ch[0]=null;
     74     x->p=null;
     75 }
     76 node *findroot(node *x){
     77     access(x);
     78     splay(x);
     79     while(x->pushdown(),x->ch[0]!=null)x=x->ch[0];
     80     return x;
     81 }
     82 void splay(node *x){
     83     x->pushdown();
     84     while(!isroot(x)){
     85         if(!isroot(x->p))x->p->p->pushdown();
     86         x->p->pushdown();
     87         x->pushdown();
     88         if(isroot(x->p)){
     89             rot(x->p,dir(x)^1);
     90             break;
     91         }
     92         if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
     93         else rot(x->p,dir(x)^1);
     94         rot(x->p,dir(x)^1);
     95     }
     96 }
     97 void rot(node *x,int d){
     98     node *y=x->ch[d^1];
     99     x->ch[d^1]=y->ch[d];
    100     if(y->ch[d]!=null)y->ch[d]->p=x;
    101     y->p=x->p;
    102     if(!isroot(x))x->p->ch[dir(x)]=y;
    103     y->ch[d]=x;
    104     x->p=y;
    105 }
    View Code

     

    COGS29 公路建设

    只有加边的动态MST,LCT维护即可。

    注意加虚点来维护边权。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<map>
      5 #define isroot(x) ((x)->p==null||((x)->p->ch[0]!=(x)&&(x)->p->ch[1]!=(x)))
      6 #define dir(x) ((int)((x)==(x)->p->ch[1]))
      7 using namespace std;
      8 const int maxn=510;
      9 struct node{
     10     int data,mx,pos;
     11     node *ch[2],*p;
     12     bool rev;
     13     node(int d):data(d),mx(d),pos(-1),rev(false){}
     14     void pushdown(){
     15         if(!rev)return;
     16         if(pos!=-1)pos^=1;
     17         ch[0]->rev^=true;
     18         ch[1]->rev^=true;
     19         swap(ch[0],ch[1]);
     20         rev=false;
     21     }
     22     void refresh(){
     23         mx=data;
     24         pos=-1;
     25         if(ch[0]->mx>mx){
     26             mx=ch[0]->mx;
     27             pos=0;
     28         }
     29         if(ch[1]->mx>mx){
     30             mx=ch[1]->mx;
     31             pos=1;
     32         }
     33     }
     34 }*null=new node(-1000000);
     35 node *newnode(int);
     36 node *access(node*);
     37 void makeroot(node*);
     38 void cut(node*,node*);
     39 void link(node*,node*);
     40 node *getroot(node*);
     41 node *getmax(node*,node*);
     42 void splay(node*);
     43 void rot(node*,int);
     44 map<node*,pair<node*,node*> >mp;
     45 node *iter[maxn];
     46 int n,m,cnt=0,x,y,w,ans=0;
     47 node *tmp;
     48 int main(){
     49     freopen("road.in","r",stdin);
     50     freopen("road.out","w",stdout);
     51     null->ch[0]=null->ch[1]=null->p=null;
     52     scanf("%d%d",&n,&m);
     53     for(int i=1;i<=n;i++)iter[i]=newnode(-1000000);
     54     while(m--){
     55         scanf("%d%d%d",&x,&y,&w);
     56         if(getroot(iter[x])!=getroot(iter[y])){
     57             tmp=newnode(w);
     58             mp[tmp]=make_pair(iter[x],iter[y]);
     59             link(tmp,iter[x]);
     60             link(tmp,iter[y]);
     61             ans+=w;
     62             cnt++;
     63         }
     64         else{
     65             node *tmp=getmax(iter[x],iter[y]);
     66             if(tmp->data>w){
     67                 ans-=tmp->data;
     68                 cut(tmp,mp[tmp].first);
     69                 cut(tmp,mp[tmp].second);
     70                 tmp->data=w;
     71                 mp[tmp]=make_pair(iter[x],iter[y]);
     72                 link(tmp,iter[x]);
     73                 link(tmp,iter[y]);
     74                 ans+=w;
     75             }
     76         }
     77         if(cnt==n-1)printf("%.1lf
    ",(double)ans/2.0);
     78         else printf("0
    ");
     79     }
     80     return 0;
     81 }
     82 node *newnode(int d){
     83     node *x=new node(d);
     84     x->ch[0]=x->ch[1]=x->p=null;
     85     return x;
     86 }
     87 node *access(node *x){
     88     node *y=null;
     89     while(x!=null){
     90         splay(x);
     91         x->ch[1]=y;
     92         (y=x)->refresh();
     93         x=x->p;
     94     }
     95     return y;
     96 }
     97 void makeroot(node *x){
     98     access(x);
     99     splay(x);
    100     x->rev^=true;
    101 }
    102 void cut(node *x,node *y){
    103     makeroot(x);
    104     access(y);
    105     splay(y);
    106     x->p=null;
    107     y->ch[0]=null;
    108     y->refresh();
    109 }
    110 void link(node *x,node *y){
    111     makeroot(x);
    112     x->p=y;
    113 }
    114 node *getroot(node *x){
    115     x=access(x);
    116     while(x->pushdown(),x->ch[0]!=null)x=x->ch[0];
    117     splay(x);
    118     return x;
    119 }
    120 node *getmax(node *x,node *y){
    121     makeroot(x);
    122     x=access(y);
    123     while(x->pushdown(),x->pos!=-1)x=x->ch[x->pos];
    124     return x;
    125 }
    126 void splay(node *x){
    127     x->pushdown();
    128     while(!isroot(x)){
    129         if(!isroot(x->p))x->p->p->pushdown();
    130         x->p->pushdown();
    131         x->pushdown();
    132         if(isroot(x->p)){
    133             rot(x->p,dir(x)^1);
    134             break;
    135         }
    136         if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
    137         else rot(x->p,dir(x)^1);
    138         rot(x->p,dir(x)^1);
    139     }
    140 }
    141 void rot(node *x,int d){
    142     node *y=x->ch[d^1];
    143     x->ch[d^1]=y->ch[d];
    144     if(y->ch[d]!=null)y->ch[d]->p=x;
    145     y->p=x->p;
    146     if(!isroot(x))x->p->ch[dir(x)]=y;
    147     y->ch[d]=x;
    148     x->p=y;
    149     x->refresh();
    150     y->refresh();
    151 }
    View Code

     

    水管局长数据加强版

    (附一个bzoj上本题的链接)

    只有删边的动态MST,时光倒流之后就转成了只有加边的动态MST,仍然LCT维护。

    话说初始MST一开始我是直接用LCT构建的,后来一看怎么我跑得这么慢才发现大家都是用的Kruskal……然后写了一发Prim,发现仍然很慢……= =

    直接LCT:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<map>
      5 #define isroot(x) ((x)->p==null||((x)->p->ch[0]!=(x)&&(x)->p->ch[1]!=(x)))
      6 #define dir(x) ((int)((x)==(x)->p->ch[1]))
      7 using namespace std;
      8 const int maxn=1000010;
      9 template<class T>inline void readint(T &x){
     10     static int c=0;
     11     x=0;
     12     while(c!=EOF&&(c<'0'||c>'9'))c=getchar();
     13     if(c==EOF)return;
     14     while(c>='0'&&c<='9'){
     15         x=(x<<1)+(x<<3)+(c^48);
     16         c=getchar();
     17     }
     18 }
     19 struct node{
     20     int data,mx,pos;
     21     node *ch[2],*p;
     22     bool rev;
     23     node(int d=-1000000):data(d),mx(d),pos(-1),rev(false){}
     24     void pushdown(){
     25         if(!rev)return;
     26         if(pos!=-1)pos^=1;
     27         ch[0]->rev^=true;
     28         ch[1]->rev^=true;
     29         swap(ch[0],ch[1]);
     30         rev=false;
     31     }
     32     void refresh(){
     33         mx=data;
     34         pos=-1;
     35         if(ch[0]->mx>mx){
     36             mx=ch[0]->mx;
     37             pos=0;
     38         }
     39         if(ch[1]->mx>mx){
     40             mx=ch[1]->mx;
     41             pos=1;
     42         }
     43     }
     44 }nodes[maxn<<1],*null=nodes,*ptr;
     45 struct A{int tp,x,y,w;}a[maxn<<1];
     46 node *newnode(int);
     47 node *access(node*);
     48 void makeroot(node*);
     49 void link(node*,node*);
     50 void cut(node*,node*);
     51 node *getroot(node*);
     52 node *getmax(node*,node*);
     53 void splay(node*);
     54 void rot(node*,int);
     55 int n,m,q,ans[maxn<<1];
     56 map<node*,pair<node*,node*> >mp;
     57 map<pair<int,int>,int>e;
     58 int main(){
     59     freopen("tube_strong.in","r",stdin);
     60     freopen("tube_strong.out","w",stdout);
     61     null->ch[0]=null->ch[1]=null->p=null;
     62     readint(n);
     63     readint(m);
     64     readint(q);
     65     ptr=nodes+n;
     66     for(int i=1;i<=n;i++)nodes[i].ch[0]=nodes[i].ch[1]=nodes[i].p=null;
     67     while(m--){
     68         int x,y,w;
     69         readint(x);
     70         readint(y);
     71         readint(w);
     72         if(x>y)swap(x,y);
     73         e[make_pair(x,y)]=w;
     74     }
     75     m=q;
     76     for(int i=1;i<=m;i++){
     77         readint(a[i].tp);
     78         readint(a[i].x);
     79         readint(a[i].y);
     80         if(a[i].x>a[i].y)swap(a[i].x,a[i].y);
     81         if(a[i].tp==2){
     82             a[i].w=e[make_pair(a[i].x,a[i].y)];
     83             e.erase(make_pair(a[i].x,a[i].y));
     84         }
     85     }
     86     for(map<pair<int,int>,int>::iterator it=e.begin();it!=e.end();it++){
     87         a[++m].tp=2;
     88         a[m].x=it->first.first;
     89         a[m].y=it->first.second;
     90         a[m].w=it->second;
     91     }
     92     for(int i=m;i;i--){
     93         int x=a[i].x,y=a[i].y,w=a[i].w;
     94         if(a[i].tp==1)ans[i]=getmax(nodes+x,nodes+y)->data;
     95         else{
     96             node *tmp;
     97             if(getroot(nodes+x)!=getroot(nodes+y)){
     98                 tmp=newnode(w);
     99                 link(tmp,nodes+x);
    100                 link(tmp,nodes+y);
    101                 mp[tmp]=make_pair(nodes+x,nodes+y);
    102             }
    103             else{
    104                 tmp=getmax(nodes+x,nodes+y);
    105                 if(tmp->data>w){
    106                     cut(tmp,mp[tmp].first);
    107                     cut(tmp,mp[tmp].second);
    108                     tmp->data=w;
    109                     link(tmp,nodes+x);
    110                     link(tmp,nodes+y);
    111                     mp[tmp]=make_pair(nodes+x,nodes+y);
    112                 }
    113             }
    114         }
    115     }
    116     for(int i=1;i<=m;i++)if(a[i].tp==1)printf("%d
    ",ans[i]);
    117     return 0;
    118 }
    119 node *newnode(int d){
    120     *++ptr=node(d);
    121     ptr->ch[0]=ptr->ch[1]=ptr->p=null;
    122     return ptr;
    123 }
    124 node *access(node *x){
    125     node *y=null;
    126     while(x!=null){
    127         splay(x);
    128         x->ch[1]=y;
    129         (y=x)->refresh();
    130         x=x->p;
    131     }
    132     return y;
    133 }
    134 void makeroot(node *x){
    135     access(x);
    136     splay(x);
    137     x->rev^=true;
    138 }
    139 void link(node *x,node *y){
    140     makeroot(x);
    141     x->p=y;
    142 }
    143 void cut(node *x,node *y){
    144     makeroot(x);
    145     access(y);
    146     splay(y);
    147     y->ch[0]=null;
    148     x->p=null;
    149     y->refresh();
    150 }
    151 node *getroot(node *x){
    152     x=access(x);
    153     while(x->pushdown(),x->ch[0]!=null)x=x->ch[0];
    154     splay(x);
    155     return x;
    156 }
    157 node *getmax(node *x,node *y){
    158     makeroot(x);
    159     x=access(y);
    160     while(x->pushdown(),x->pos!=-1)x=x->ch[x->pos];
    161     splay(x);
    162     return x;
    163 }
    164 void splay(node *x){
    165     x->pushdown();
    166     while(!isroot(x)){
    167         if(!isroot(x->p))x->p->p->pushdown();
    168         x->p->pushdown();
    169         x->pushdown();
    170         if(isroot(x->p)){
    171             rot(x->p,dir(x)^1);
    172             break;
    173         }
    174         if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
    175         else rot(x->p,dir(x)^1);
    176         rot(x->p,dir(x)^1);
    177     }
    178 }
    179 void rot(node *x,int d){
    180     node *y=x->ch[d^1];
    181     x->ch[d^1]=y->ch[d];
    182     if(y->ch[d]!=null)y->ch[d]->p=x;
    183     y->p=x->p;
    184     if(!isroot(x))x->p->ch[dir(x)]=y;
    185     y->ch[d]=x;
    186     x->p=y;
    187     x->refresh();
    188     y->refresh();
    189 }
    View Code

    Prim:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<map>
      5 #include<vector>
      6 #include<queue>
      7 #define isroot(x) ((x)->p==null||((x)->p->ch[0]!=(x)&&(x)->p->ch[1]!=(x)))
      8 #define dir(x) ((int)((x)==(x)->p->ch[1]))
      9 using namespace std;
     10 const int maxn=1000010;
     11 template<class T>inline void readint(T &x){
     12     static int c=0;
     13     x=0;
     14     while(c!=EOF&&(c<'0'||c>'9'))c=getchar();
     15     if(c==EOF)return;
     16     while(c>='0'&&c<='9'){
     17         x=(x<<1)+(x<<3)+(c^48);
     18         c=getchar();
     19     }
     20 }
     21 struct node{
     22     int data,mx,pos;
     23     node *ch[2],*p;
     24     bool rev;
     25     node(int d=-1000000):data(d),mx(d),pos(-1),rev(false){}
     26     void pushdown(){
     27         if(!rev)return;
     28         if(pos!=-1)pos^=1;
     29         ch[0]->rev^=true;
     30         ch[1]->rev^=true;
     31         swap(ch[0],ch[1]);
     32         rev=false;
     33     }
     34     void refresh(){
     35         mx=data;
     36         pos=-1;
     37         if(ch[0]->mx>mx){
     38             mx=ch[0]->mx;
     39             pos=0;
     40         }
     41         if(ch[1]->mx>mx){
     42             mx=ch[1]->mx;
     43             pos=1;
     44         }
     45     }
     46 }nodes[maxn<<1],*null=nodes,*ptr;
     47 struct oper{int tp,x,y,w;}a[maxn];
     48 struct A{
     49     int x,dis;
     50     A(int x,int dis):x(x),dis(dis){}
     51     bool operator<(const A &a)const{return dis>a.dis;}
     52 };
     53 void Prim();
     54 node *newnode(int);
     55 node *access(node*);
     56 void makeroot(node*);
     57 void link(node*,node*);
     58 void cut(node*,node*);
     59 node *getmax(node*,node*);
     60 void splay(node*);
     61 void rot(node*,int);
     62 vector<int>G[maxn],W[maxn];
     63 int dis[maxn],prt[maxn]={0};
     64 bool vis[maxn]={false};
     65 int n,m,q,ans[maxn];
     66 map<node*,pair<node*,node*> >mp;
     67 map<pair<int,int>,int>e;
     68 int main(){
     69     freopen("tube_strong.in","r",stdin);
     70     freopen("tube_strong.out","w",stdout);
     71     null->ch[0]=null->ch[1]=null->p=null;
     72     readint(n);
     73     readint(m);
     74     readint(q);
     75     ptr=nodes+n;
     76     for(int i=1;i<=n;i++)nodes[i].ch[0]=nodes[i].ch[1]=nodes[i].p=null;
     77     while(m--){
     78         int x,y,w;
     79         readint(x);
     80         readint(y);
     81         readint(w);
     82         if(x>y)swap(x,y);
     83         e[make_pair(x,y)]=w;
     84     }
     85     m=q;
     86     for(int i=1;i<=m;i++){
     87         readint(a[i].tp);
     88         readint(a[i].x);
     89         readint(a[i].y);
     90         if(a[i].x>a[i].y)swap(a[i].x,a[i].y);
     91         if(a[i].tp==2){
     92             a[i].w=e[make_pair(a[i].x,a[i].y)];
     93             e.erase(make_pair(a[i].x,a[i].y));
     94         }
     95     }
     96     for(map<pair<int,int>,int>::iterator it=e.begin();it!=e.end();it++){
     97         G[it->first.first].push_back(it->first.second);
     98         W[it->first.first].push_back(it->second);
     99         G[it->first.second].push_back(it->first.first);
    100         W[it->first.second].push_back(it->second);
    101     }
    102     Prim();
    103     for(int i=m;i;i--){
    104         int x=a[i].x,y=a[i].y,w=a[i].w;
    105         if(a[i].tp==1)ans[i]=getmax(nodes+x,nodes+y)->data;
    106         else{
    107             node *tmp=getmax(nodes+x,nodes+y);
    108             if(tmp->data>w){
    109                 cut(tmp,mp[tmp].first);
    110                 cut(tmp,mp[tmp].second);
    111                 tmp->data=w;
    112                 link(tmp,nodes+x);
    113                 link(tmp,nodes+y);
    114                 mp[tmp]=make_pair(nodes+x,nodes+y);
    115             }
    116         }
    117     }
    118     for(int i=1;i<=m;i++)if(a[i].tp==1)printf("%d
    ",ans[i]);
    119     return 0;
    120 }
    121 void Prim(){
    122     fill(dis+1,dis+n+1,0x3f3f3f3f);
    123     priority_queue<A>q;
    124     dis[1]=0;
    125     q.push(A(1,0));
    126     while(!q.empty()){
    127         int x=q.top().x;
    128         q.pop();
    129         if(vis[x])continue;
    130         vis[x]=true;
    131         for(int i=0;i<(int)G[x].size();i++)if(!vis[G[x][i]]&&dis[G[x][i]]>W[x][i]){
    132             dis[G[x][i]]=W[x][i];
    133             prt[G[x][i]]=x;
    134             q.push(A(G[x][i],W[x][i]));
    135         }
    136     }
    137     for(int i=2;i<=n;i++){
    138         node *x=newnode(dis[i]);
    139         x->p=nodes+prt[i];
    140         nodes[i].p=x;
    141         mp[x]=make_pair(nodes+min(prt[i],i),nodes+max(prt[i],i));
    142     }
    143 }
    144 node *newnode(int d){
    145     *++ptr=node(d);
    146     ptr->ch[0]=ptr->ch[1]=ptr->p=null;
    147     return ptr;
    148 }
    149 node *access(node *x){
    150     node *y=null;
    151     while(x!=null){
    152         splay(x);
    153         x->ch[1]=y;
    154         (y=x)->refresh();
    155         x=x->p;
    156     }
    157     return y;
    158 }
    159 void makeroot(node *x){
    160     access(x);
    161     splay(x);
    162     x->rev^=true;
    163 }
    164 void link(node *x,node *y){
    165     makeroot(x);
    166     x->p=y;
    167 }
    168 void cut(node *x,node *y){
    169     makeroot(x);
    170     access(y);
    171     splay(y);
    172     y->ch[0]=null;
    173     x->p=null;
    174     y->refresh();
    175 }
    176 node *getmax(node *x,node *y){
    177     makeroot(x);
    178     x=access(y);
    179     while(x->pushdown(),x->pos!=-1)x=x->ch[x->pos];
    180     splay(x);
    181     return x;
    182 }
    183 void splay(node *x){
    184     x->pushdown();
    185     while(!isroot(x)){
    186         if(!isroot(x->p))x->p->p->pushdown();
    187         x->p->pushdown();
    188         x->pushdown();
    189         if(isroot(x->p)){
    190             rot(x->p,dir(x)^1);
    191             break;
    192         }
    193         if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
    194         else rot(x->p,dir(x)^1);
    195         rot(x->p,dir(x)^1);
    196     }
    197 }
    198 void rot(node *x,int d){
    199     node *y=x->ch[d^1];
    200     x->ch[d^1]=y->ch[d];
    201     if(y->ch[d]!=null)y->ch[d]->p=x;
    202     y->p=x->p;
    203     if(!isroot(x))x->p->ch[dir(x)]=y;
    204     y->ch[d]=x;
    205     x->p=y;
    206     x->refresh();
    207     y->refresh();
    208 }
    View Code

    话说这两份代码bzoj上都T到死,也是没谁了……

     

    bzoj2001 [Hnoi2010]City 城市建设

    这才是真·动态MST……

    听说有个算法叫CDQ重构图,然而太神了并不能看懂,于是乎写了一发对时间分治+LCT,常数大如dog,成功被卡掉……

    反正各种卡常都过不去,我还是贴没卡常的代码好了……

      1 /**************************************************************
      2     Problem: 2001
      3     User: hzoier
      4     Language: C++
      5     Result: Time_Limit_Exceed
      6 ****************************************************************/
      7  
      8 #include<cstdio>
      9 #include<cstring>
     10 #include<algorithm>
     11 #include<vector>
     12 #include<map>
     13 #define isroot(x) ((x)->p==null||((x)->p->ch[0]!=(x)&&(x)->p->ch[1]!=(x)))
     14 #define dir(x) ((int)((x)==(x)->p->ch[1]))
     15 using namespace std;
     16 const int maxn=20010,maxm=50010;
     17 struct node{
     18     int data,mx,pos;
     19     node *ch[2],*p;
     20     bool rev;
     21     node(int d=-1000000):data(d),mx(d),pos(-1),rev(false){}
     22     void pushdown(){
     23         if(!rev)return;
     24         if(pos!=-1)pos^=1;
     25         ch[0]->rev^=1;
     26         ch[1]->rev^=1;
     27         swap(ch[0],ch[1]);
     28         rev=false;
     29     }
     30     void refresh(){
     31         mx=data;
     32         pos=-1;
     33         if(ch[0]->mx>mx){
     34             mx=ch[0]->mx;
     35             pos=0;
     36         }
     37         if(ch[1]->mx>mx){
     38             mx=ch[1]->mx;
     39             pos=1;
     40         }
     41     }
     42 }nodes[maxn<<1],*null=nodes,*ptr=nodes;
     43 struct edge{int x,y,t,w;}e[maxm];
     44 struct A{
     45     node *x,*u,*v;
     46     int w;
     47     A(node *x,node *u,node *v,int w):x(x),u(u),v(v),w(w){}
     48 };
     49 void addedge(int,int,int);
     50 void solve(int,int,int,long long);
     51 node *newnode(int);
     52 node *access(node*);
     53 void makeroot(node*);
     54 void link(node*,node*);
     55 void cut(node*,node*);
     56 node *getmax(node*,node*);
     57 node *getroot(node*);
     58 void splay(node*);
     59 void rot(node*,int);
     60 vector<int>u[maxm<<2],v[maxm<<2],w[maxm<<2];
     61 map<node*,pair<node*,node*> >mp;
     62 int n,m,q,s,t,k,x,y,z;
     63 node *tmp;
     64 int main(){
     65     null->ch[0]=null->ch[1]=null->p=null;
     66     scanf("%d%d%d",&n,&m,&q);
     67     for(int i=1;i<=n;i++)newnode(-100000000);
     68     for(int i=1;i<n;i++){
     69         tmp=newnode(100000000);
     70         link(tmp,nodes+i);
     71         link(tmp,nodes+i+1);
     72         mp[tmp]=make_pair(nodes+i,nodes+i+1);
     73     }
     74     for(int i=1;i<=m;i++){
     75         scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
     76         if(e[i].x>e[i].y)swap(e[i].x,e[i].y);
     77         e[i].t=1;
     78     }
     79     for(int i=1;i<=q;i++){
     80         scanf("%d%d",&k,&z);
     81         x=e[k].x;y=e[k].y;
     82         s=e[k].t;t=i-1;
     83         swap(e[k].w,z);
     84         if(t)addedge(1,q,1);
     85         e[k].t=i;
     86     }
     87     for(int i=1;i<=m;i++){
     88         s=e[i].t;t=q;
     89         x=e[i].x;y=e[i].y;z=e[i].w;
     90         addedge(1,q,1);
     91     }
     92     solve(1,q,1,(long long)(n-1)*100000000);
     93     return 0;
     94 }
     95 void addedge(int l,int r,int rt){
     96     if(s<=l&&t>=r){
     97         u[rt].push_back(x);
     98         v[rt].push_back(y);
     99         w[rt].push_back(z);
    100         return;
    101     }
    102     int mid=(l+r)>>1;
    103     if(s<=mid)addedge(l,mid,rt<<1);
    104     if(t>mid)addedge(mid+1,r,rt<<1|1);
    105 }
    106 void solve(int l,int r,int rt,long long ans){
    107     vector<A>stk;
    108     for(int i=0;i<(int)u[rt].size();i++){
    109         tmp=getmax(nodes+u[rt][i],nodes+v[rt][i]);
    110         if(tmp->data>w[rt][i]){
    111             stk.push_back(A(tmp,mp[tmp].first,mp[tmp].second,tmp->data));
    112             cut(tmp,mp[tmp].first);
    113             cut(tmp,mp[tmp].second);
    114             ans-=tmp->data;
    115             mp[tmp]=make_pair(nodes+u[rt][i],nodes+v[rt][i]);
    116             tmp->data=w[rt][i];
    117             link(tmp,nodes+u[rt][i]);
    118             link(tmp,nodes+v[rt][i]);
    119             ans+=w[rt][i];
    120         }
    121     }
    122     if(l==r)printf("%lld
    ",ans);
    123     else{
    124         int mid=(l+r)>>1;
    125         solve(l,mid,rt<<1,ans);
    126         solve(mid+1,r,rt<<1|1,ans);
    127     }
    128     if(!stk.empty())for(int i=(int)stk.size()-1;i>=0;i--){
    129         cut(stk[i].x,mp[stk[i].x].first);
    130         cut(stk[i].x,mp[stk[i].x].second);
    131         mp[stk[i].x]=make_pair(stk[i].u,stk[i].v);
    132         stk[i].x->data=stk[i].w;
    133         link(stk[i].x,stk[i].u);
    134         link(stk[i].x,stk[i].v);
    135     }
    136 }
    137 node *newnode(int d){
    138     *++ptr=node(d);
    139     ptr->ch[0]=ptr->ch[1]=ptr->p=null;
    140     return ptr;
    141 }
    142 node *access(node *x){
    143     node *y=null;
    144     while(x!=null){
    145         splay(x);
    146         x->ch[1]=y;
    147         (y=x)->refresh();
    148         x=x->p;
    149     }
    150     return y;
    151 }
    152 void makeroot(node *x){
    153     access(x);
    154     splay(x);
    155     x->rev^=true;
    156 }
    157 void link(node *x,node *y){
    158     makeroot(x);
    159     x->p=y;
    160 }
    161 void cut(node *x,node *y){
    162     makeroot(x);
    163     access(y);
    164     splay(y);
    165     y->ch[0]=null;
    166     x->p=null;
    167     y->refresh();
    168 }
    169 node *getmax(node *x,node *y){
    170     makeroot(x);
    171     x=access(y);
    172     while(x->pushdown(),x->pos!=-1)x=x->ch[x->pos];
    173     splay(x);
    174     return x;
    175 }
    176 node *getroot(node *x){
    177     x=access(x);
    178     while(x->pushdown(),x->ch[0]!=null)x=x->ch[0];
    179     splay(x);
    180     return x;
    181 }
    182 void splay(node *x){
    183     x->pushdown();
    184     while(!isroot(x)){
    185         if(!isroot(x->p))x->p->p->pushdown();
    186         x->p->pushdown();
    187         x->pushdown();
    188         if(isroot(x->p)){
    189             rot(x->p,dir(x)^1);
    190             break;
    191         }
    192         if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
    193         else rot(x->p,dir(x)^1);
    194         rot(x->p,dir(x)^1);
    195     }
    196 }
    197 void rot(node *x,int d){
    198     node *y=x->ch[d^1];
    199     x->ch[d^1]=y->ch[d];
    200     if(y->ch[d]!=null)y->ch[d]->p=x;
    201     y->p=x->p;
    202     if(!isroot(x))x->p->ch[dir(x)]=y;
    203     y->ch[d]=x;
    204     x->p=y;
    205     x->refresh();
    206     y->refresh();
    207 }
    View Code

    话说写这题的时候调了半天,最后发现我pushdown的时候忘了交换左右儿子,真是智障……

     

    感觉这几道题还好吧……每道题都是重新打的LCT(虽然调不出来的时候会拿出上一题的代码手动FC……),感觉考试考到的话模板应该是打不错了。

    LCT真是累啊……算了我接下来还是专心搞网络流好了……

  • 相关阅读:
    pycharm破解补丁的使用
    C# 解析JSON格式数据
    LINQ to DataSet的DataTable操作
    日期格式化
    vue scoped原理
    vue父子组件生命周期执行顺序
    js判断同一天和同一周
    flex总结
    react-router v4 参数传递
    link标签rel="alternate"属性的作用及用法
  • 原文地址:https://www.cnblogs.com/hzoier/p/6242377.html
Copyright © 2011-2022 走看看