• SDOI2013 森林


    题目链接:戳我

    呜呜呜又被dreagonm嘲讽了,但是我真的不会写数据结构啊QAQ

    链上求第K大+启发式合并

    (以下是重构第三遍的代码QAQ)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 100010
    using namespace std;
    int n,m,lastans,tt,sum,tot,T,q;
    int f[MAXN],siz[MAXN],p[MAXN][19];
    int fa[MAXN],dep[MAXN],rt[MAXN],S[MAXN],a[MAXN],head[MAXN];
    struct Edge{int nxt,to;}edge[MAXN<<1];
    struct Node{int ls,rs,v;}t[MAXN<<9];
    inline void add(int from,int to){edge[++tt].nxt=head[from],edge[tt].to=to,head[from]=tt;}
    inline void update(int &x,int f,int l,int r,int pos)
    {
        x=++tot;
        t[x]=t[f],t[x].v++;
        if(l==r) return;
        int mid=(l+r)>>1;
        if(pos<=mid) update(t[x].ls,t[f].ls,l,mid,pos);
        else update(t[x].rs,t[f].rs,mid+1,r,pos);
    }
    inline int query(int x,int y,int lca1,int lca2,int l,int r,int k)
    {
        if(l==r) return l;
        int cur=t[t[x].ls].v+t[t[y].ls].v-t[t[lca1].ls].v-t[t[lca2].ls].v;
        int mid=(l+r)>>1;
        if(k<=cur) return query(t[x].ls,t[y].ls,t[lca1].ls,t[lca2].ls,l,mid,k);
        else return query(t[x].rs,t[y].rs,t[lca1].rs,t[lca2].rs,mid+1,r,k-cur);
    }
    inline int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
    inline void merge(int x,int y)
    {
        int xx=find(x),yy=find(y);
        f[xx]=yy;
        siz[yy]+=siz[xx],siz[xx]=0;
    }
    inline int get_lca(int x,int y)
    {
        if(dep[x]<dep[y]) swap(x,y);
        int cur=dep[x]-dep[y];
        for(int i=17;i>=0;i--)
            if(cur&(1<<i))
                x=p[x][i];
        if(x==y) return x;
        for(int i=17;i>=0;i--)
            if(p[x][i]!=p[y][i])
                x=p[x][i],y=p[y][i];
        return fa[x];
    }
    inline void dfs(int x,int pre)
    {
        fa[x]=p[x][0]=pre;
        dep[x]=dep[pre]+1;
        update(rt[x],rt[pre],1,sum,a[x]);
        for(int i=1;i<=17;i++)
            p[x][i]=p[p[x][i-1]][i-1];
        for(int i=head[x];i;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(v==pre) continue;
            dfs(v,x);
        }
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d",&T);
        memset(head,0,sizeof(head));
        tt=0;
        scanf("%d%d%d",&n,&m,&q);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),siz[i]=1;
        memcpy(S,a,sizeof(a));
        sort(&S[1],&S[n+1]);
        sum=unique(&S[1],&S[n+1])-S-1;
        for(int i=1;i<=n;i++) a[i]=lower_bound(&S[1],&S[sum+1],a[i])-S;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y),add(y,x);
            if(siz[find(x)]>siz[find(y)]) merge(y,x);
            else merge(x,y);
        }
        for(int i=1;i<=n;i++)
        {
            if(!rt[i])
                dfs(i,0);
        }
        lastans=0;
        for(int i=1;i<=q;i++)
        {
            char s[10];
            int x,y,k;
            scanf("%s",s);
            if(s[0]=='Q')
            {
                scanf("%d%d%d",&x,&y,&k);
                x^=lastans,y^=lastans,k^=lastans;
                int lca=get_lca(x,y);
                printf("%d
    ",lastans=S[query(rt[x],rt[y],rt[lca],rt[fa[lca]],1,sum,k)]);
            }
            else 
            {
                scanf("%d%d",&x,&y);
                x^=lastans,y^=lastans;
                if(siz[find(x)]>siz[find(y)]) swap(x,y);
                merge(x,y);
                dfs(x,y);
                add(x,y),add(y,x);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    bzoj1336: [Balkan2002]Alien最小圆覆盖
    bzoj3564: [SHOI2014]信号增幅仪
    [HDU5353]
    [codeforce1072D]
    [dp001]逛公园
    树上问题泛做
    [BZOJ2599]race
    [CEOI2019]MAGIC TREE
    [BZOJ2836]魔法树
    QTREE3
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10803052.html
Copyright © 2020-2023  润新知