笛卡尔树模版
按第一关键字排序,然后按第二关键字构建笛卡尔树即可。
#include <bits/stdc++.h> #define INF 0x3f3f3f3f #define full(a, b) memset(a, b, sizeof a) #define __fastIn ios::sync_with_stdio(false), cin.tie(0) #define pb push_back using namespace std; typedef long long LL; inline int lowbit(int x){ return x & (-x); } inline int read(){ int ret = 0, w = 0; char ch = 0; while(!isdigit(ch)){ w |= ch == '-', ch = getchar(); } while(isdigit(ch)){ ret = (ret << 3) + (ret << 1) + (ch ^ 48); ch = getchar(); } return w ? -ret : ret; } template <typename A> inline A __lcm(A a, A b){ return a / __gcd(a, b) * b; } template <typename A, typename B, typename C> inline A fpow(A x, B p, C lyd){ A ans = 1; for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd; return ans; } const int N = 60000; int n, x, y; vector< pair<pair<int, int>, int> > v; struct Node{ int i, val; Node *fa, *lf, *rf; Node(){} Node(int i, int val, Node *fa, Node *lf, Node *rf): i(i), val(val), fa(fa), lf(fa), rf(rf){} }*null, *root; bool cmp(Node *a, Node *b){ return a->i < b->i; } Node *buildTree(){ stack<Node *> st; Node *last = null; for(int i = 0; i < v.size(); i ++){ Node *cur = new Node(v[i].second, v[i].first.second, null, null, null); while(!st.empty()){ if(st.top()->val < cur->val){ Node *up = st.top(); if(up->rf != null) cur->lf = up->rf, up->rf->fa = cur; up->rf = cur, cur->fa = up; break; } last = st.top(), st.pop(); } if(st.empty() && last) cur->lf = last, last->fa = cur; st.push(cur); } Node *root = null; while(!st.empty()) root = st.top(), st.pop(); return root; } vector<Node *> ans; void dfs(Node *cur){ if(cur == null) return; ans.pb(cur); dfs(cur->lf), dfs(cur->rf); } int main(){ n = read(); for(int i = 0; i < n; i ++){ x = read(), y = read(); v.pb(make_pair(make_pair(x, y), i + 1)); } sort(v.begin(), v.end()); null = new Node(0, 0, NULL, NULL, NULL); root = buildTree(); dfs(root); sort(ans.begin(), ans.end(), cmp); puts("YES"); for(int i = 0; i < ans.size(); i ++){ printf("%d %d %d\n", ans[i]->fa->i, ans[i]->lf->i, ans[i]->rf->i); } return 0; }