20pts 求助
查看原帖
20pts 求助
242931
zjqzjq楼主2023/7/15 23:43
#include<bits/stdc++.h>
#define int long long
#define ls tr[x].lc
#define rs tr[x].rc
using namespace std;
const int N=1e6+10;
int n,q;
int L[N],R[N],V[N],head[N],tail[N],tot=0;
int siz[N],rt[N],cnt=0;
struct tree{
    int lc,rc,id,val;
}tr[N*32];
void pushup(int x){
    if(tr[ls].val>tr[rs].val) tr[x].val=tr[ls].val,tr[x].id=tr[ls].id;
    else tr[x].val=tr[rs].val,tr[x].id=tr[rs].id;
}
void update(int &x,int l,int r,int p,int v){
    if(!x) x=++cnt;
    if(l==r){
        if(!tr[x].id) tr[x].id=l;
        tr[x].val+=v;
        return;
    }
    int mid=(l+r)/2;
    if(p<=mid) update(ls,l,mid,p,v);
    else update(rs,mid+1,r,p,v);
    pushup(x);
}
int getval(int &x,int l,int r,int p){
    if(x==0) return 0;
    if(l==r) return tr[x].val;
    int mid=(l+r)/2;
    if(p<=mid) return getval(ls,l,mid,p);
    return getval(rs,mid+1,r,p);
}
int merge(int x,int y,int l,int r){
    if(!x||!y) return x^y;
    if(l==r){
        tr[x].val+=tr[y].val;
        return x;
    }
    int mid=(l+r)/2;
    tr[x].lc=merge(tr[x].lc,tr[y].lc,l,mid);
    tr[x].rc=merge(tr[x].rc,tr[y].rc,mid+1,r);
    pushup(x);
    return x;
}
signed main(){
    cin>>n>>q;
    for(int i=1;i<=n;i++){
        scanf("%lld",siz+i);
        for(int j=1;j<=siz[i];j++){
            int x; scanf("%lld",&x);
            update(rt[i],0,n+q+1,x,1);
            if(!head[i]) V[head[i]=tail[i]=++tot]=x;
            else R[tail[i]]=++tot,L[tot]=tail[i],tail[i]=tot,V[tot]=x;
        }
    }
    for(int zjq=1;zjq<=q;zjq++){
        int o; scanf("%lld",&o);
        if(o==1){
            int x,y; scanf("%lld%lld",&x,&y);
            R[tail[x]]=++tot,L[tot]=tail[x],tail[x]=tot,V[tot]=y;
            update(rt[x],0,n+q+1,y,1);
            siz[x]++;
        }
        else if(o==2){
            int x; scanf("%lld",&x);
            update(rt[x],0,n+q+1,V[tail[x]],-1);
            siz[x]--;
            tail[x]=L[tail[x]],L[R[tail[x]]]=0,R[tail[x]]=0;
        }
        else if(o==3){
            int m,num=-1,tm=0;
            vector<int> _;
            scanf("%lld",&m);
            while(m--){
                int x; scanf("%lld",&x);
                _.push_back(x);
                if(tr[rt[x]].val*2>siz[x]){
                    int tmp=tr[rt[x]].val*2-siz[x];
                    if(tmp<tm) tm-=tmp;
                    else num=tr[rt[x]].id,tm=tmp-tm;
                }
            }
            int sum=0;
            if(num==-1){puts("-1");continue;}
            for(int u:_){
                sum+=2*getval(rt[u],0,n+q+1,num)-siz[u];
            }
            if(sum>0) printf("%lld\n",num);
            else puts("-1");
        }
        else{
            int x,y,z; scanf("%lld%lld%lld",&x,&y,&z);
            if(siz[x]==0){
                siz[z]=siz[y],head[z]=head[y],tail[z]=tail[y];
                rt[z]=rt[y];
                continue;
            }
            if(siz[y]==0){
                siz[z]=siz[x],head[z]=head[x],tail[z]=tail[x];
                rt[z]=rt[x];
                continue;
            }
            head[z]=head[x],tail[z]=tail[y];
            R[tail[x]]=head[y],L[head[y]]=tail[x];
            siz[z]=siz[x]+siz[y];
            rt[z]=merge(rt[x],rt[y],0,n+q+1);
        }
    }
    return 0;
}

2023/7/15 23:43
加载中...