[POJ2201]Cartesian Tree

题意

给你每个节点的a与k两个权值,问能否建出一棵笛卡尔树,满足对于一个节点他所有右儿子的k值小于其k值,所有左儿子的k值大于其k值,且其祖先的a值小于其a值。若可以,输出每个节点的父节点,右儿子,左儿子。

 

题解

因为题目保证所有的a各不相同,k各不相同,故一定可以建立出一棵符合条件的笛卡尔树,直接建树即可。(排序后的标号处理有点麻烦。。。)

注意POJ这里不能用万能头文件

 

代码

 

#include <cstdio>
#include <algorithm>



using namespace std;

const int MAXN=5e4+5;

int st[MAXN],N;
struct node{
	int k,a;
	int id;
}p[MAXN];

struct tree{
	int fa;
	int l,r;
}tr[MAXN];

bool cmp(node x,node y){
	return x.k<y.k;
}

int main(){
	scanf("%d",&N);
	for(int i=1;i<=N;i++){
		scanf("%d%d",&p[i].k,&p[i].a);
		p[i].id=i;
	}
	sort(p+1,p+1+N,cmp);
	int top=1;
	st[top]=1;
	for(int i=2;i<=N;i++){
		while(top&&p[st[top]].a>p[i].a) top--;
		if(!top){
			tr[p[st[1]].id].fa=p[i].id;
			tr[p[i].id].l=p[st[1]].id;
		}else{
			tr[p[i].id].l=tr[p[st[top]].id].r;
			tr[tr[p[i].id].l].fa=p[i].id;
			tr[p[i].id].fa=p[st[top]].id;
			tr[p[st[top]].id].r=p[i].id;
		}
		st[++top]=i;
	}
	puts("YES");
	for(int i=1;i<=N;i++){
		printf("%d %d %d\n",tr[i].fa,tr[i].l,tr[i].r);
	}
	return 0;
} 

  

posted @ 2020-12-16 18:01  EDawn  阅读(97)  评论(0)    收藏  举报