社区讨论

萌新刚学OI,全部TLE求助QAQ

P3224[HNOI2012] 永无乡参与者 6已保存回复 6

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
6 条
当前快照
1 份
快照标识符
@mi865e53
此快照首次捕获于
2025/11/21 09:15
4 个月前
此快照最后确认于
2025/11/21 09:15
4 个月前
查看原帖
用Splay启发式合并,每次合并把size小的Splay全取出来再一个一个insert到大的里面 (我菜)
是我复杂度假了?如果假了的话请问怎么合并啊QAQ
复杂度不假的话就是写挂了,求DALAO帮忙康康_(」∠)_
CPP
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int read(){
	int x=0;char ch=getchar();int pos=1;
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;
	for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
	return pos?x:-x; 
}
const int N=5000001;
int n,m,q;
int ff[N],val[N],rt[N],son[N][2],sz[N],tot,rb[N<<2],b[N],top,lnk[N],a[N],fa[N];
int gf(int num){
	if(num==ff[num]) return num;
	else {
		ff[num]=gf(ff[num]);
		return ff[num];
	}
}
void push_up(int x){
	sz[x]=sz[son[x][1]]+sz[son[x][0]]+1;
}
int get(int x){
	return (x==son[fa[x]][1]);
}
void rotate(int x){
	int f=fa[x];int g=fa[f];
	int gx=get(x),gf=get(f);
	fa[son[x][gx^1]]=f;
	 son[f][gx]=son[x][gx^1];
	fa[f]=x;
	 son[x][gx^1]=f;
	 fa[x]=g;
	 son[g][gf]=x;
	push_up(f);
	push_up(x); 
}
void splay(int x,int v,int i){
	while(fa[x]!=v){
		int f=fa[x];
		if(fa[f]!=v){
			rotate((get(x)==get(f))?f:x); 
		}
		rotate(x);
	}
	if(v==0) rt[i]=x;
}
void find(int i,int x){
	int now=rt[i];
	while(son[now][val[now]>x]){
		now=son[now][val[now]>x];
	}
	splay(now,0,i);
}
void insert(int i,int x){
	int now=rt[i],p;
	while(val[now]!=x&&now){
		p=now;
		now=son[now][val[now]<x];
	}
	if(top){
		now=rb[top--];
	}else now=++tot;
	val[now]=x;
	fa[now]=p;
	son[p][x>val[p]]=now;
	sz[now]=1;
	sz[p]++;
	son[now][1]=son[now][0]=0;
	splay(now,0,i);
}
char S[10];
int ava[N],hie;
void add(int v){
	if(val[v]==192608170||val[v]==-192608170) return;
	rb[++top]=v;
	ava[++hie]=val[v];
	if(son[v][1]) add(son[v][1]);
	if(son[v][0]) add(son[v][0]);
}
int kth(int i,int k){
	k++;
	int now=rt[i];
	while(k){
		if(sz[son[now][0]]>k){
			now=son[now][0];
		}else if(k==sz[son[now][0]]+1){
			return lnk[val[now]];
		}else{
			k-=(sz[son[now][0]]+1);
			now=son[now][1];
		}
	}
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++){
		a[i]=read();
		b[i]=a[i];
	}
	sort(b+1,b+n+1);
	for(int i=1;i<=n;i++){
		a[i]=lower_bound(b+1,b+n+1,a[i])-b;
		lnk[a[i]]=i;
	}
	for(int i=1;i<=n;i++){
		ff[i]=i;
		rt[i]=++tot;
		fa[tot]=0;
		val[tot]=a[i];
		sz[tot]=3;
		int xx=tot;
		
		son[xx][1]=++tot;
		val[tot]=192608170;
		sz[tot]=1;
		son[tot][0]=son[tot][1]=0;
		fa[tot]=xx;
		
		son[xx][0]=++tot;
		val[tot]=-192608170;
		sz[tot]=1;
		son[tot][0]=son[tot][1]=0;
		fa[tot]=xx;
	}
	int u,v; 
	for(int i=1;i<=m;i++){
		u=read(),v=read();
		int fu=gf(u),fv=gf(v);
		if(fu==fv) continue;
		if(sz[rt[fu]]<sz[rt[fv]]) swap(fu,fv);
		hie=0;
		add(rt[fv]);
		for(int i=1;i<=hie;i++){
			insert(fu,ava[i]);
		}
		ff[fv]=fu;
	}
	int q=read();
	for(int i=1;i<=q;i++){
		scanf("%s",S);
		u=read(),v=read();
		if(S[0]=='Q'){
			int fu=gf(u);
			if(sz[rt[fu]]-2<v){
				printf("-1\n");
				continue;
			}else{
				printf("%d\n",kth(fu,v));
			}
		}else{
			int fu=gf(u),fv=gf(v);
			if(fu==fv) continue;
			if(sz[rt[fu]]<sz[rt[fv]]) swap(fu,fv);
			hie=0;
			add(rt[fv]);
			for(int i=1;i<=hie;i++){
				insert(fu,ava[i]);
			}
			ff[fv]=fu;
		}
	}
	return 0;
} 

回复

6 条回复,欢迎继续交流。

正在加载回复...