BZOJ 2733 [HNOI2012] Neverland (segment tree heuristic combined weights + disjoint-set)

Meaning of the questions:

FIG. 1e5 of n = <, the even-line edge, a communication block query k-th largest

Ideas:

Exercise combined segment tree good question, because terror still remember the last time when the heuristic merge trie memory of the explosion, so this point is still open with the dynamic recovery

I heard heuristic merge splay faster QAQ, learned to try

Code:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional>
     
#define fst first
#define sc second
#define pb push_back
#define mp make_pair
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x))
 
using namespace std;
 
typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;
 
const db eps = 1e-6;
const int mod = 1e9+7;
const int maxn = 1e5+100;
const int maxm = 6e6+100;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0);

int n,m;
int q;
int ls[maxn*66],rs[maxn*66],dat[maxn*66];
int root[maxn];
int a[maxn],id[maxn];

int f[maxn];
int find(int x){
    return f[x]==x?x:f[x]=find(f[x]);
}

int tot;
queue<int>pool;
int New(){
    if(!pool.empty()){
        int x = pool.front();
        pool.pop();
        return x;
    }
    ++tot;
    return tot;
}
void del(int x){
    if(!x)return;
    pool.push(x);
    return;
}
int build(int l, int r, int x){
    int mid = (l+r)>>1;
    int p = New();
    dat[p]=1;
    if(l==r)return p;
    if(x<=mid)ls[p]=build(l,mid,x);
    else rs[p]=build(mid+1,r,x);
    return p;
}
int merge(int p, int q){// leave p
    if(!p)return q;
    if(!q)return p;
    ls[p]=merge(ls[p],ls[q]);
    rs[p]=merge(rs[p],rs[q]);
    dat[p]+=dat[q];
    ls[q]=rs[q]=dat[q]=0;
    del(q);
    return p;
}
int query(int x, int l, int r, int k){
    int mid = (l+r)>>1;
    if(l==r)return l;
    if(dat[ls[x]]>=k){
        return query(ls[x],l,mid,k);
    }
    else{
        return query(rs[x],mid+1,r,k-dat[ls[x]]);
    }
}
int main() {
    scanf("%d %d" ,&n, &m);
    for(int i = 1; i <= n; i++){
        f[i]=i;
        scanf("%d", &a[i]);
        id[a[i]]=i;
        root[i]=build(1,n,a[i]);
    }
    /*for(int i = 1; i <= n; i++){
        printf("-- %d root::%d\n",i,root[i]);
    }
    for(int i = 1; i <= tot; i++){
        //printf("%d ==== %d %d %d\n",i,ls[i],rs[i],dat[i]);
    }*/
    for(int i = 1; i <= m; i++){
        int x,y;
        scanf("%d %d" ,&x, &y);
        int t1 = find(x);
        int t2 = find(y);
        if(t1!=t2){
            root[t1]=merge(root[t1],root[t2]);
            f[t2]=t1;
        }
    }
    scanf("%d", &q);
    while(q--){
        char op[5];
        int x,y;
        scanf("%s %d %d", op,&x,&y);
        if(op[0]=='Q'){
            int t = find(x);
            if(dat[root[t]]<y){printf("-1\n");continue;}
            else printf("%d\n",id[query(root[t],1,n,y)]);
        }
        else{
            int t1 = find(x);
            int t2 = find(y);
            if(t1!=t2){
                root[t1]=merge(root[t1],root[t2]);
                f[t2]=t1;
            }
        }
    }
    return 0;
}
/*
5 1
4 3 2 5 1
1 2
7
Q 3 2
Q 2 1
B 2 3
B 1 5
Q 2 1
Q 2 4
Q 2 3
 */

 

Guess you like

Origin www.cnblogs.com/wrjlinkkkkkk/p/10977311.html