码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj3123: [Sdoi2013]森林 主席树+启发式合并

时间:2016-07-23 07:22:58      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:

思博题加强版,还是思博题,RT,没了。

内存log^2,写了回收的话可以少个log。

lca不能用树剖了好悲伤(IoI),讨厌倍增。

没有1A好不爽啊啊啊,最近写思博题只有一道1A的是要退役的节奏(@_@)

#include<cstdio>
#include<algorithm>
#define N 80005
#define M (l+r>>1)
using namespace std;
char o[2];
int k,m,q,s,t,u,v,x,y;
struct node{
	node* c[2];
	int s;
}c[N*300],*next=c+1;
node* f[N];
int query(int k,node* s,
node* t,node* u,node* v){
	int i,j,r=m,l=1;
	while(l!=r){
		j=s->s+t->s
		-u->s-v->s;
		i=k>j,k-=i*j;
		s=s->c[i];
		t=t->c[i];
		u=u->c[i];
		v=v->c[i];
		i?l=M+1:r=M;
	}
	return l;
}
void add(int v,node* s,
node** t){
	int i,r=m,l=1;
	while(l!=r){
		*t=next++;
		**t=*s,i=v>M;
		(*t)->s+=i^1;
		s=s->c[i];
		t=&(*t)->c[i];
		i?l=M+1:r=M;
	}
}
struct edge{
	edge* s;
	int v;
}e[N*2],*back=e,*h[N];
void add(int u,int v){
	h[u]=&(*back++
	=(edge){h[u],v});
	h[v]=&(*back++
	=(edge){h[v],u});
}
typedef int ds[N];
ds a[16+1],&p=*a,d,r,z,l;
void dfs(int u){
	add(l[u],f[p[u]],f+u);
	r[u]=1;
	d[u]=d[p[u]]+1;
	for(int j=0;j!=16;++j)
		a[j+1][u]
		=a[j][a[j][u]];
	for(edge* i=h[u];i;i=i->s)
		if(i->v!=p[u]){
			p[i->v]=u;
			dfs(i->v);
			r[u]+=r[i->v];
		}
}
int lca(int s,int t){
	if(d[s]<d[t])
		swap(s,t);
	for(int j=0;d[s]
	^d[t];++j)
		s=d[s]-d[t]&1<<j
		?a[j][s]:s;
	for(int j=16;~j;--j)
		if(a[j][s]^a[j][t]){
			s=a[j][s];
			t=a[j][t];
		}
	return s^t?p[s]:s;
}
int find(int s){
	for(int j=16;~j;--j)
		if(a[j][s])
			s=a[j][s];
	return s;
}
int main(){
	*f=&(*c=(node){c,c});
	scanf("%*d%d%d%d",
	&m,&x,&y);
	for(int i=1;i<=m;++i){
		scanf("%d",l+i);
		z[i]=l[i];
	}
	sort(z+1,z+m+1);
	for(int i=1;i<=m;++i)
		l[i]=lower_bound(
		z+1,z+m+1,l[i])-z;
	while(x--){
		scanf("%d%d",&s,&t);
		add(s,t);
	}
	for(int i=1;i<=m;++i)
		if(!d[i])
			dfs(i);
	while(y--){
		scanf("%s%d%d",o,&s,&t);
		s^=q,t^=q;
		if(*o==‘L‘){
			add(s,t);
			u=find(s),v=find(t);
			if(r[u]<r[v]){
				r[v]+=r[u];
				p[s]=t,dfs(s);
			}else{
				r[u]+=r[v];
				p[t]=s,dfs(t);
			}
		}else{
			scanf("%d",&k);
			u=lca(s,t);
			printf("%d\n",q=z[
			query(k^q,f[s],
			f[t],f[u],f[p[u]])]);
		}
	}
}

  

bzoj3123: [Sdoi2013]森林 主席树+启发式合并

标签:

原文地址:http://www.cnblogs.com/f321dd/p/5697723.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!