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

bzoj2827: 千山鸟飞绝 treap

时间:2016-08-01 06:55:03      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:

离散化坐标,每个坐标开一棵以鸟的编号为关键字的平衡树。每次插入时打2个标记,同时更新自身。这个方法比较显然,而且好写。正解好像用很迷的方法乱搞了一波,然后用线段树不打标记就做出来了,并不会。

treap旋转没传引用,调了好久。

#include<bits/stdc++.h>
#define N 30005
#define M 330005
#define x first
#define y second
#define IF else if
using namespace std;
int n,m,i,v[M];
typedef int ds[N];
ds f,l,r,z;
typedef pair<int,int> vec;
vec a[M],s[M];
struct node{
	int v,a,i,j,s,q;
	node *r,*l;
}*t[M],e[M];
node* back=e+1;
node* null=e;
node* create(int v){
	return &(*back++
	=(node){v,z[v],
	0,0,1,rand(),e,e});
}
void update(node* t){
	t->s=t->l->s
	+t->r->s+1;
	t->a=max(max(
	t->l->a,
	t->r->a),z[t->v]);
}
void lturn(node*& t){
	node* s=t->r;
	t->r=s->l;
	update(s->l=t);
	update(t=s);
}
void rturn(node*& t){
	node* s=t->l;
	t->l=s->r;
	update(s->r=t);
	update(t=s);
}
void eq2(int& a,int b){
	a=a<b?b:a;
}
void devolve(node* s){
	eq2(s->l->i,s->i);
	eq2(s->l->j,s->j);
	eq2(s->r->i,s->i);
	eq2(s->r->j,s->j);
	eq2(l[s->v],s->i);
	eq2(r[s->v],s->j);
	s->i=s->j=0;
}
void insert(int v,
node*& s){
	if(s==null)
		s=create(v);
	devolve(s);
	if(v<s->v){
		insert(v,s->l);
		if(s->l->q>s->q)
			rturn(s);
	}IF(s->v<v){
		insert(v,s->r);
		if(s->r->q>s->q)
			lturn(s);
	}
	update(s);
}
void erase(int v,
node*& s){
	devolve(s);
	if(v<s->v)
		erase(v,s->l);
	IF(s->v<v)
		erase(v,s->r);
	IF(s->l==null){
		s=s->r;
		return;
	}IF(s->r==null){
		s=s->l;
		return;
	}IF(s->l->q>s->r->q){
		devolve(s->l);
		rturn(s);
		erase(v,s->r);
	}else{
		devolve(s->r);
		lturn(s);
		erase(v,s->l);
	}
	update(s);
}
void come(int v,
node*& s){
	eq2(s->i,z[v]);
	eq2(s->j,s->s);
	eq2(l[v],s->a);
	eq2(r[v],s->s);
	insert(v,s);
}
void dfs(node* t){
	if(t!=null){
		devolve(t);
		dfs(t->l);
		dfs(t->r);
	}
}
int main(){
	srand(20000327);
	scanf("%d",&n);
	for(i=1;i<=n;++i){
		scanf("%d%d%d",z+i,
		&a[i].x,&a[i].y);
		s[i]=a[i];
	}
	scanf("%d",&m);
	for(i=n+1;i<=n+m;++i){
		scanf("%d%d%d",v+i,
		&a[i].x,&a[i].y);
		s[i]=a[i];
	}
	sort(s+1,s+n+m+1);
	for(i=1;i<=n+m;++i)
		t[i]=null;
	for(i=1;i<=n;++i)
		come(i,t[f[i]
		=lower_bound(
		s+1,s+n+m+1,a[i])-s]);
	for(i=n+1;i<=n+m;++i){
		erase(v[i],
		t[f[v[i]]]);
		come(v[i],t[f[v[i]]
		=lower_bound(
		s+1,s+n+m+1,a[i])-s]);
	}
	for(i=1;i<=n;++i){
		dfs(t[f[i]]);
		t[f[i]]=null;
		printf("%lld"
		"\n",1ll*l[i]*r[i]);
	}
}

  

bzoj2827: 千山鸟飞绝 treap

标签:

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

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