一堆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\n",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\n":"No\n");
    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\n":"No\n");
 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\n",(double)ans/2.0);
 78         else printf("0\n");
 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\n",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\n",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\n",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真是累啊……算了我接下来还是专心搞网络流好了……

posted @ 2017-01-02 13:59  AntiLeaf  阅读(254)  评论(0编辑  收藏  举报