P8496 [NOI2022] 众数
include_BM · · 题解
每个序列开一颗动态开点权值线段树,每个节点维护子树和,那么
考虑
但是只有权值线段树无法得知序列最后一个数是什么,那么可以对每个序列开一个链表,维护每个序列的开头、末尾、每个数的值以及每个数上一个数是什么,那么合并两个序列时只需要把
注意
//People who believe in miracles are as amazing as miracles themselves.
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-f;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
const int N=1e6+10;
int n,q,m,len[N],val[N],ed[N],st[N],pre[N],rt[N],cnt,tot,p[N],num; ll need;
#define mid ((l+r)>>1)
struct node{
int ls,rs,num;
}tr[N*25];
void chg(int &x,int l,int r,int p,int k){
if(!x) x=++tot; tr[x].num+=k;
if(l!=r) p<=mid?chg(tr[x].ls,l,mid,p,k):chg(tr[x].rs,mid+1,r,p,k);
}
int merge(int x,int y,int l,int r){
if(!x||!y) return x+y;
if(l==r) return tr[x].num+=tr[y].num,x;
tr[x].ls=merge(tr[x].ls,tr[y].ls,l,mid);
tr[x].rs=merge(tr[x].rs,tr[y].rs,mid+1,r);
return tr[x].num=tr[tr[x].ls].num+tr[tr[x].rs].num,x;
}
int que(int l,int r){
ll sum=0;
if(l==r){
for(int i=1;i<=num;++i) sum+=tr[p[i]].num; return sum>=need?l:-1;
}
for(int i=1;i<=num;++i) sum+=tr[tr[p[i]].ls].num;
if(sum>=need){
for(int i=1;i<=num;++i) p[i]=tr[p[i]].ls; return que(l,mid);
}
else{
for(int i=1;i<=num;++i) p[i]=tr[p[i]].rs; return que(mid+1,r);
}
}
signed main(){
n=read(),q=read(),m=n+q;
for(int i=1;i<=n;++i){
len[i]=read();
for(int j=1;j<=len[i];++j){
++cnt;
if(!st[i]) st[i]=cnt; else pre[cnt]=ed[i];
val[cnt]=read(),chg(rt[i],1,m,val[cnt],1),ed[i]=cnt;
}
}
for(int op,x,y,z;q;--q){
op=read();
if(op==1){
x=read(),y=read(),++len[x],++cnt;
if(!st[x]) st[x]=cnt; else pre[cnt]=ed[x];
val[cnt]=y,chg(rt[x],1,m,y,1),ed[x]=cnt;
}
else if(op==2){
x=read(),--len[x];
chg(rt[x],1,m,val[ed[x]],-1),ed[x]=pre[ed[x]]; if(!ed[x]) st[x]=0;
}
else if(op==3){
num=read(),need=0;
for(int i=1;i<=num;++i) p[i]=read(),need+=len[p[i]],p[i]=rt[p[i]];
need=need/2+1,printf("%d\n",que(1,m));
}
else{
x=read(),y=read(),z=read();
len[z]=len[x]+len[y];
if(st[x]&&st[y]) st[z]=st[x],ed[z]=ed[y],pre[st[y]]=ed[x];
else if(st[x]) st[z]=st[x],ed[z]=ed[x];
else if(st[y]) st[z]=st[y],ed[z]=ed[y];
rt[z]=merge(rt[x],rt[y],1,m),rt[x]=rt[y]=st[x]=st[y]=ed[x]=ed[y]=len[x]=len[y]=0;
}
}
return 0;
}