题意:根据给出的key和val的值,构造一棵笛卡尔树。
思路:一个裸题,不过以前没写过笛卡尔树,这东西意外的好写……首先按key值排序,然后依次插入,可以看出后插入的节点一定是在最右侧,剩下就是根据val的值去改变树的形态,用一个栈去存当前的右链,当插入一个新节点时,从栈中找到第一个比当前节点小的节点作为当前节点的父亲,其他节点为当前节点的左子树。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<set> #include<stack> #include<cmath> #include<vector> #define inf 0x3f3f3f3f #define Inf 0x3FFFFFFFFFFFFFFFLL #define eps 1e-9 #define pi acos(-1.0) using namespace std; typedef long long ll; const int maxn=50000+10; int pa[maxn],lson[maxn],rson[maxn]; int conv[maxn]; struct Node { int id,va,vb; bool operator <(const Node &a) const { return va<a.va; } }node[maxn]; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); memset(pa,0,sizeof(pa)); memset(lson,0,sizeof(lson)); memset(rson,0,sizeof(rson)); int n; scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%d%d",&node[i].va,&node[i].vb); node[i].id=i; } sort(node+1,node+n+1); conv[node[1].id]=1; stack<int>S; S.push(1); for(int i=2;i<=n;++i) { conv[node[i].id]=i; int fp=0,sp=0; while(!S.empty()) { int tmp=S.top(); //pa[sp]=tmp; if(node[tmp].vb<node[i].vb) { fp=tmp; break; } else { //pa[tmp] sp=tmp; S.pop(); } } pa[i]=fp; rson[fp]=i; lson[i]=sp; pa[sp]=i; S.push(i); } printf("YES\n"); for(int i=1;i<=n;++i) { int p=conv[i]; printf("%d %d %d\n",node[pa[p]].id,node[lson[p]].id,node[rson[p]].id); } return 0; }