BZOJ 3319: 黑白树 并查集 + 离线 + 思维

Code: 

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#define setIO(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)  
#define maxn 1002002
using namespace std;  
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;}
vector<int>G[maxn]; 
stack<int>S;                  
int n,m,edges; 
int tm[maxn],hd[maxn<<1],to[maxn<<1],nex[maxn<<1];     
int siz[maxn],top[maxn],fa[maxn],dep[maxn],son[maxn]; 
int idx[maxn<<1],id[maxn<<1];     
inline void addedge(int u,int v,int c) {
    nex[++edges]=hd[u],hd[u]=edges,to[edges]=v, id[edges]=c;   
}
void dfs1(int u,int ff) {
    dep[u]=dep[ff]+1,siz[u]=1,fa[u]=ff; 
    for(int i=hd[u];i;i=nex[i]) {
        int v=to[i];     
        if(v==ff) continue; 
        idx[v]=id[i], dfs1(v,u), siz[u]+=siz[v]; 
        if(siz[v] > siz[son[u]]) son[u] = v;  
    }
}
void dfs2(int u,int tp) {
    top[u]=tp; 
    if(son[u]) dfs2(son[u], tp); 
    for(int i=hd[u];i;i=nex[i]) {
        int v=to[i]; 
        if(v==fa[u] || v==son[u]) continue; 
        dfs2(v,v); 
    }
}
inline int LCA(int x,int y) {
    while(top[x]^top[y]) {
        dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]]; 
    }
    return dep[x]<dep[y]?x:y; 
}
struct Opt {
    int opt,x,y;
}op[maxn]; 
struct Union {
    int p[maxn]; 
    inline void init() {
        for(int i=0;i<maxn;++i) p[i]=i; 
    }
    int find(int x) {
        return p[x]==x?x:p[x]=find(p[x]); 
    }
}black,white;         
inline void mark(int u,int lca,int cur) {
    u=tm[u]?black.find(u):u;  
    while(dep[u]>dep[lca]) {
        tm[u]=cur;      
        if(!tm[fa[u]]) {
            black.p[u]=fa[u];   
            u=fa[u];   
        }    
        else {
            int y=black.find(fa[u]);          
            black.p[u]=y;          
            u=y;                  
        }
    }
}
inline void update(int u,int v,int cur) {
    int lca=LCA(u,v); 
    mark(u,lca,cur), mark(v,lca,cur);     
}
inline void change(int u) {
    white.p[u]=white.find(fa[u]);                
}
int main() {
    // setIO("input"); 
    scanf("%d%d",&n,&m); 
    for(int i=1;i<n;++i) {
        int u,v; 
        u=rd(),v=rd(); 
        addedge(u,v,i),addedge(v,u,i);         
    }
    dfs1(1,0), dfs2(1,1), black.init();                      
    for(int i=1;i<=m;++i) {
        op[i].opt=rd(); 
        if(op[i].opt==1) op[i].x=rd(); 
        if(op[i].opt==2) op[i].x=rd(), op[i].y=rd(), update(op[i].x,op[i].y,i);  
    }   
    white.init(); 
    for(int i=2;i<=n;++i) G[tm[i]==0?m+1:tm[i]].push_back(i);  
    m+=(G[m+1].size()>1); 
    for(int i=m;i>=1;--i) {      
        if(G[i].size()) {
            for(int j=0;j<G[i].size();++j) change(G[i][j]);        
        }else if(op[i].opt==1) {
            S.push(white.find(op[i].x));                 
        }
    }             
    while(!S.empty()) {
        printf("%d\n",idx[S.top()]); S.pop(); 
    }
    return 0; 
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/11235798.html