zoukankan      html  css  js  c++  java
  • bzoj3123: [Sdoi2013]森林

    题目链接

    bzoj3123: [Sdoi2013]森林

    题解

    树上差分+主席树启发式合并

    代码

    #include<cstdio> 
    #include<cstring> 
    #include<algorithm> 
     
    inline int read() { 
        int x = 0,f = 1; 
        char c = getchar(); 
        while(c < '0' || c > '9') c = getchar(); 
        while(c <= '9' && c >= '0')x = x * 10 + c - '0',c = getchar(); 
        return x * f; 
    } 
     
    const int maxn = 100007; 
    struct NNnode {
        int v,next; 
    } edge[maxn << 1]; 
    int num = 0,head[maxn]; 
    inline void add_edge(int u,int v)  { 
        edge[++ num].v = v;edge[num].next = head[u];head[u] = num; 
    } 
     
    int root[maxn],val[maxn],n,m,t,MX; 
    int cnt_node = 0; 
    int ls[maxn * 20],rs[maxn * 20],cnt[maxn * 20]; 
    void insert(int pre,int &now,int l,int r,int key) { 
        cnt[++ cnt_node] = cnt[now]; now = cnt_node; 
        ++ cnt[now]; 
        if(l == r) return ; 
        int mid = l + r >> 1; 
        ls[now] = ls[pre]; rs[now] = rs[pre]; 
        if(key <= mid) insert(ls[pre],ls[now],l,mid,key); 
        else insert(rs[pre],rs[now],mid + 1,r,key);  
    } 
     
    int query(int t1,int t2,int t3,int t4,int l,int r,int k) { 
        if (l == r) return l; 
        int mid = l + r >> 1; 
        int dtl = cnt[ls[t1]] + cnt[ls[t2]] - cnt[ls[t3]] - cnt[ls[t4]]; 
        if(k <= dtl) return query(ls[t1],ls[t2],ls[t3],ls[t4],l,mid,k); 
        else return query(rs[t1],rs[t2],rs[t3],rs[t4],mid + 1,r,k - dtl);  
    } 
     
    int root_num[maxn],siz[maxn], dep[maxn],dad[maxn][22]; 
    void dfs(int x) { 
        siz[x] = 1; 
        for(int i = 0;dad[x][i];++ i)dad[x][i + 1] = dad[dad[x][i]][i]; 
        insert(root[dad[x][0]],root[x],1,MX,val[x]); 
        for(int i = head[x];i;i = edge[i].next) { 
            int v = edge[i].v; 
            if(v == dad[x][0]) continue; 
            root_num[v] = root_num[x]; 
            dad[v][0] = x; dep[v] = dep[x] + 1; 
            dfs(v); 
            siz[x] += siz[v]; 
        } 
    } 
     
    int LCA(int x,int y) { 
        if(dep[x] > dep[y]) std::swap(x,y); 
        for(int i = 18;i >= 0;i --) if(dep[dad[y][i]] >= dep[x]) y = dad[y][i]; 
        if(x == y) return x; 
        for(int i = 18;i >= 0;i --) if(dad[y][i] != dad[x][i]) y = dad[y][i],x = dad[x][i]; 
        return dad[x][0]; 
    } 
    int work_q(int x,int y,int k) { 
        int lca = LCA(x,y); 
        //printf(" ************ %d
    ",lca);
        int F_lca = dad[lca][0]; 
        return query(root[x],root[y],root[lca],root[dad[lca][0]],1,MX,k); 
    } 
    void work_L(int x,int y) { 
        int lca = LCA(x,y); 
        dad[y][0] = x; 
        siz[root_num[x]] += siz[root_num[y]]; 
        root_num[y] = root_num[x]; 
        dep[y] = dep[x] + 1; 
        dfs(y); 
    } 
    void solve() { 
        num = 0,memset(head,0,sizeof head); 
        memset(root_num,0,sizeof root_num);memset(root,0,sizeof root); 
        memset(cnt,0,sizeof cnt); 
        cnt_node = MX = 0; 
        n = read(),m = read(); t = read(); 
        for(int i = 1;i <= n;++ i) val[i] = read(),MX = std::max(val[i],MX); 
        for(int x,y,i = 1;i <= m;++ i) { 
            x = read(), y = read(); 
            add_edge(x,y) , add_edge(y,x);  
        } 
        for(int i = 1;i <= n;++ i) 
            if(!root_num[i]) root_num[i] = i,dep[i] = 1,dfs(i); 
        char opt[20]; 
        int lans = 0; 
        while(t --) { 
            scanf("%s",opt + 1) ; 
            if(opt[1] == 'Q')  { 
                int x = read() ^ lans,y = read() ^ lans, k = read() ^ lans; 
                printf("%d
    ",lans = work_q(x,y,k)); 
            } else {
                int x = read() ^ lans,y = read() ^ lans; 
                if(siz[root_num[x]] < siz[root_num[y]]) std::swap(x,y); 
                work_L(x,y); 
            } 
        } 
    } 
    int main() { 
        //int testcase = read(); 
        //for(int i = 1;i <= testcase;++ i) solve();  
         
    } 
    
    
  • 相关阅读:
    QT槽和信号机制介绍
    J2EE面试题之二
    .net 面试题系列文章一(附答案)
    SUN JAVA面试笔试题
    用友在清华的笔试题
    Java面试笔试题整理
    雅虎公司C#笔试题(之一)
    Oracle面试题及答案整理
    一些著名的大公司JAVA面试题目
    百度技术研发笔试题目1
  • 原文地址:https://www.cnblogs.com/sssy/p/9452786.html
Copyright © 2011-2022 走看看