POJ 2201 Cartesian Tree ——笛卡尔树
【题目分析】
构造一颗笛卡尔树,然后输出这棵树即可。
首先进行排序,然后用一个栈维护最右的树的节点信息,插入的时候按照第二关键字去找,找到之后插入,下面的树成为它的左子树即可。
然后插入分三种情况讨论(最下面,中间,成为了新的树根)
【代码】
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; struct node{ int k,a,id; }a[50005],st[50005]; int ans[50005][3]; int cmp(node a,node b) {return a.k<b.k;} int n; void solve() { node now; int top=0,x,y,z; st[top++]=a[1]; for (int i=2;i<=n;++i) { int flag=0; while (top>0&&st[top-1].a>a[i].a) { flag=1; now=st[--top]; } if (!flag) { x=st[top-1].id; y=a[i].id; ans[x][2]=y; ans[y][0]=x; st[top++]=a[i]; } else { if (top) { x=st[top-1].id; y=a[i].id; z=now.id; ans[x][2]=y; ans[y][0]=x; ans[z][0]=y; ans[y][1]=z; st[top++]=a[i]; } else { y=a[i].id; z=now.id; ans[y][1]=z; ans[z][0]=y; st[top++]=a[i]; } } } } int main() { scanf("%d",&n); for (int i=1;i<=n;++i) { scanf("%d%d",&a[i].k,&a[i].a); a[i].id=i; } sort(a+1,a+n+1,cmp); solve(); printf("YES\n"); for (int i=1;i<=n;++i) printf("%d %d %d\n",ans[i][0],ans[i][1],ans[i][2]); }