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\n",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();

}

 

上一篇:P3226 [HNOI2012]集合选数 状压DP


下一篇:[bzoj2733] [HNOI2012] 永无乡