主席树 但是能够想到题解的做法很难
#include <stdio.h> #include <string.h> #include <vector> #include <algorithm> using namespace std; const int MAXN = 500010; int n; vector<int> p[50010]; int T[50010]; struct Node{ int s; int ls, rs; }tree[MAXN * 16]; int tot; int x[50010]; int add(int x,int l,int r,int pre) { int rt = ++tot; tree[rt] = tree[pre]; tree[rt].s ++; if(l == r) return rt; int m = (l+r) >>1; if(x <= m) tree[rt].ls = add(x,l,m,tree[pre].ls); else tree[rt].rs = add(x,m+1,r,tree[pre].rs); return rt; } int query(int s,int t,int l, int r, int rt1, int rt2){ if(s <= l && r <= t) return tree[rt2].s-tree[rt1].s; int m = (l+r) >>1; int ans = 0; if(s <= m) ans += query(s,t,l,m,tree[rt1].ls,tree[rt2].ls); if(t > m) ans += query(s,t,m+1,r,tree[rt1].rs,tree[rt2].rs); return ans; } void init() { for (int i = 1; i <= 50000; ++i) p[i].clear(); while (n--) { int x, y; scanf("%d%d", &x, &y); p[x].push_back(y); } for (int i = 1; i <= 50000; ++i) { sort(p[i].begin(), p[i].end()); p[i].erase(unique(p[i].begin(), p[i].end()), p[i].end()); } } bool solve() { tot = 0; tree[0].ls = tree[0].rs = tree[0].s = 0; T[0] = 0; memset(x, 0, sizeof(x)); for (int i = 1; i <= 50000; ++i) { T[i] = T[i - 1]; for (int j = 0; j < (int)p[i].size(); ++j) { int l = j == 0 ? 0 : p[i][j - 1]; int r = j == (int)p[i].size() - 1 ? 50001 : p[i][j + 1]; if (query( l + 1, r - 1,1,50000,T[i], T[x[p[i][j]]])) { return false; } } for (int j = 0; j < (int)p[i].size(); ++j) { T[i] = add(p[i][j], 1, 50000, T[i]); x[p[i][j]] = i; } } return true; } int main() { // freopen("1012.in","r",stdin); while (scanf("%d", &n), n > 0) { init(); puts(solve() ? "YES" : "NO"); } }