• luogu_P3224 [HNOI2012]永无乡


    并查集维护线段树合并

    b加在a上

    #include<iostream>
    #include<cstdio>
    
    #define ri register int
    #define u int
    
    namespace opt {
    
        inline u in() {
            u x(0),f(1);
            char s(getchar());
            while(s<'0'||s>'9') {
                if(s=='-') f=-1;
                s=getchar();
            }
            while(s>='0'&&s<='9') {
                x=(x<<1)+(x<<3)+s-'0';
                s=getchar();
            }
            return x*f;
        }
    
    }
    
    using opt::in;
    
    #define NN 100005
    
    namespace xds {
    
        struct node {
            u l,r,sum,add;
        } a[NN<<6];
    
        u num,ans[NN],rot[NN];
    
        void pushdown(const u &rt,const u &l,const u &r) {
            if(a[rt].add) {
                if(!a[rt].l) a[rt].l=++num;
                if(!a[rt].r) a[rt].r=++num;
                u mid((l+r)>>1);
                a[a[rt].l].add+=a[rt].add;
                a[a[rt].r].add+=a[rt].add;
                a[a[rt].l].sum+=a[rt].add*(mid-l+1);
                a[a[rt].r].sum+=a[rt].add*(r-mid);
                a[rt].add=0;
            }
        }
    
        void update(u &rt,const u &l,const u &r,const u &x,const u &y,const u &k) {
            if(!rt) rt=++num;
            if(l>=x&&r<=y) {
                a[rt].sum+=k*(r-l+1),a[rt].add+=k;
                return;
            }
            pushdown(rt,l,r);
            u mid((l+r)>>1);
            if(x<=mid) update(a[rt].l,l,mid,x,y,k);
            if(y>=mid+1) update(a[rt].r,mid+1,r,x,y,k);
            a[rt].sum=a[a[rt].l].sum+a[a[rt].r].sum;
        }
    
        u query(const u &rt,const u &l,const u &r,const u &k) {
            if(k>a[rt].sum) return -1;
            if(l==r) return ans[l];
            pushdown(rt,l,r);
            u mid((l+r)>>1);
            if(a[a[rt].l].sum>=k) return query(a[rt].l,l,mid,k);
            else return query(a[rt].r,mid+1,r,k-a[a[rt].l].sum);
        }
    
        void merge(u &x,const u &y) {
            if(!x||!y) {
                if(!x) x=y;
                return;
            }
            a[x].sum+=a[y].sum,a[x].add+=a[y].add;
            merge(a[x].l,a[y].l),merge(a[x].r,a[y].r);
        }
    
    }
    
    namespace cas {
    
        u fa[NN];
    
        u getfa(u x) {
            u _x(x),k;
            while(_x^fa[_x]) _x=fa[_x];
            while(x^_x) k=fa[x],fa[x]=_x,x=k;
            return _x;
        }
    
    }
    
    namespace mainstay {
    
        u v[NN];
    
        using namespace cas;
        using namespace xds;
    
        inline void solve() {
            u N(in()),M(in());
            for(ri i(1); i<=N; ++i) fa[i]=i;
            for(ri i(1); i<=N; ++i) v[i]=in(),ans[v[i]]=i,update(rot[getfa(i)],1,N,v[i],v[i],1);
            for(ri i(1); i<=M; ++i) {
                u _a(in()),_b(in());
                if(getfa(_a)^getfa(_b)) {
                    merge(rot[getfa(_a)],rot[getfa(_b)]);
                    fa[getfa(_b)]=getfa(_a);
                }
            }
            u Q(in());
            while(Q--) {
                char _s(getchar());
                while(_s!='Q'&&_s!='B') _s=getchar();
                u _a(in()),_b(in());
                if(_s=='Q') {
                    printf("%d
    ",query(rot[getfa(_a)],1,N,_b));
                } else {
                    if(getfa(_a)^getfa(_b)) {
                        merge(rot[getfa(_a)],rot[getfa(_b)]);
                        fa[getfa(_b)]=getfa(_a);
                    }
                }
            }
        }
    
    }
    
    int main() {
    
        //freopen("x.txt","r",stdin);
        //freopen("my.txt","w",stdout);
        std::ios::sync_with_stdio(false);
        mainstay::solve();
    
    }
  • 相关阅读:
    每日日报
    Java学习
    Java学习
    Java学习
    Java学习
    Java学习
    Java学习
    Java学习
    Java学习
    JAVA日报
  • 原文地址:https://www.cnblogs.com/ling-zhi/p/11844655.html
Copyright © 2020-2023  润新知