zoukankan      html  css  js  c++  java
  • 洛谷 P3302 [SDOI2013]森林

    ->题目链接

    题解:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 160001
    #define D 15
    using namespace std;
    char ch[5];
    int t,x,y,z;
    int n,m,qq,tot,cut,ans,father[MAXN],dis[MAXN];
    int head[MAXN],size[MAXN],deep[MAXN],root[MAXN],s[MAXN],fa[MAXN][D+5];
    struct edge {
        int v,next;
    } e[MAXN*2];
    struct data {
        int lc,rc,size;
    } tree[MAXN*75];
    struct node {
        int x,o;
    } a[MAXN];
    void add(int u,int v) {
        e[++cut].v=v;
        e[cut].next=head[u];
        head[u]=cut;
    }
    bool cmp(const node &x,const node &y) {
        if(x.x==y.x) return x.o<y.o;
        return x.x<y.x;
    }
    int find(int x) {
        return x!=father[x]?father[x]=find(father[x]):x;
    }
    void change(int &k,int last,int l,int r,int x) {
        k=++tot;
        tree[k].lc=tree[last].lc,tree[k].rc=tree[last].rc;
        tree[k].size=tree[last].size+1;
        if(l==r) return ;
        int mid=(l+r)>>1;
        if(x<=mid) change(tree[k].lc,tree[last].lc,l,mid,x);
        else change(tree[k].rc,tree[last].rc,mid+1,r,x);
        return ;
    }
    int query(int L,int R,int lc,int falc,int l,int r,int k) {
        if(l==r) return l;
        int sum=tree[tree[R].lc].size+tree[tree[L].lc].size-
                tree[tree[lc].lc].size-tree[tree[falc].lc].size;
        int mid=l+r>>1;
        if(sum>=k)
            return query(tree[L].lc,tree[R].lc,tree[lc].lc,tree[falc].lc,l,mid,k);
        else return
                query(tree[L].rc,tree[R].rc,tree[lc].rc,tree[falc].rc,mid+1,r,k-sum);
    }
    void dfs1(int u,int f) {
        size[u]=1;
        fa[u][0]=f;
        int p=lower_bound(s+1,s+n+1,a[u].x)-s;
        change(root[u],root[f],1,n,p);
        for(int i=head[u]; i; i=e[i].next) {
            int v=e[i].v;
            if(v!=f) deep[v]=deep[u]+1,dfs1(v,u),size[u]+=size[v];
        }
        return ;
    }
    void get_father() {
        for(int j=1; j<=D; j++)
            for(int i=1; i<=n; i++)
                fa[i][j]=fa[fa[i][j-1]][j-1];
        return ;
    }
    int get_same(int u,int x) {
        for(int i=0; i<=D; i++)
            if(x&(1<<i)) u=fa[u][i];
        return u;
    }
    int lca(int x,int y) {
        if(deep[x]<deep[y]) swap(x,y);
        x=get_same(x,deep[x]-deep[y]);
        if(x==y) return x;
        for(int i=D; i>=0; i--)
            if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
        return fa[x][0];
    }
    void slovequery(int x,int y,int k) {
        int lc=lca(x,y);
        ans=query(root[x],root[y],root[lc],root[fa[lc][0]],1,n,k);
        ans=s[ans];
        printf("%d
    ",ans);
        return ;
    }
    void slove(int u,int f) {
        fa[u][0]=f;
        deep[u]=deep[f]+1;
        int p=lower_bound(s+1,s+n+1,a[u].x)-s;
        change(root[u],root[f],1,n,p);
        for(int i=1; i<=D; i++) fa[u][i]=fa[fa[u][i-1]][i-1];
        for(int i=head[u]; i; i=e[i].next) {
            int v=e[i].v;
            if(v!=f) slove(v,u);
        }
        return ;
    }
    void union_(int x,int y) {
        int l1=find(x),l2=find(y);
        if(size[l1]>size[l2]) swap(l1,l2),swap(x,y);
        add(x,y),add(y,x);
        father[l1]=l2,size[l1]+=size[l2];
        slove(x,y);
        return ;
    }
    int main() {
        cin>>t>>n;
        cin>>m>>qq;
        for(int i=1; i<=n; i++)
            father[i]=i,cin>>a[i].x,a[i].o=i,s[i]=a[i].x;
        sort(s+1,s+n+1);
        for(int i=1; i<=m; i++) {
            cin>>x>>y,add(x,y),add(y,x);
            int l1=find(x),l2=find(y);
            father[l2]=l1;
        }
        for(int i=1; i<=n; i++) if(!fa[i][0]) dfs1(i,0);
        get_father();
        while(qq--) {
            scanf("%s",ch);
            if(ch[0]=='Q') {
                cin>>x>>y>>z;
                x^=ans,y^=ans,z^=ans;
                slovequery(x,y,z);
            } else {
                cin>>x>>y;
                x^=ans,y^=ans;
                union_(x,y);
            }
        }
        return 0;
    }

    一世安宁

  • 相关阅读:
    MySQL锁总结
    DDL和DML
    字节、字、位、比特之间的关系
    Mysql数据库、表设计规范指南
    Mysql性能优化关键配置指南
    3.python正则匹配不到内容时消耗大量内存
    1. postman使用
    2. python提示:TypeError: unhashable type: 'list'
    14. selenium的Page Object模型
    12.unittest的学习
  • 原文地址:https://www.cnblogs.com/GTBA/p/9456777.html
Copyright © 2011-2022 走看看