【POJ2182】Lost Cows
阿新 • • 發佈:2018-12-18
【POJ2182】Lost Cows
題面
題解
從後往前做
每掃到一個點\(i\)以及比前面小的有\(a[i]\)個數
就是查詢當前的第\(a[i]+1\)小
然後查詢完將這個數刪掉
兩個操作可以用平衡樹實現
但是我比較懶用了\(01trie\)
據說暴力也可以過
程式碼
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; inline int gi() { register int data = 0, w = 1; register char ch = 0; while (ch != '-' && (ch > '9' || ch < '0')) ch = getchar(); if (ch == '-') w = -1 , ch = getchar(); while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar(); return w * data; } const int MAX_N = 80005; struct Trie { int ch[2], size; } t[MAX_N * 18]; int tot; void insert(int v) { int o = 1; t[o].size++; for (int i = 17; i >= 0; i--) { int c = v >> i & 1; if (!t[o].ch[c]) t[o].ch[c] = ++tot; t[o = t[o].ch[c]].size++; } } void erase(int v) { int o = 1; t[o].size--; for (int i = 17; i >= 0; i--) { int c = v >> i & 1; t[o = t[o].ch[c]].size--; } } int Kth(int k) { int o = 1, res = 0; for (int i = 17; i >= 0; i--) { int sz = t[t[o].ch[0]].size; if (k <= sz) o = t[o].ch[0]; else k -= sz, res |= 1 << i, o = t[o].ch[1]; } return res; } int N, a[MAX_N], ans[MAX_N]; int main () { N = gi(); for (int i = 1; i < N; i++) a[i + 1] = gi(); ++tot; for (int i = 1; i <= N; i++) insert(i); for (int i = N; i >= 1; i--) { ans[i] = Kth(a[i] + 1); erase(ans[i]); } for (int i = 1; i <= N; i++) printf("%d\n", ans[i]); return 0; }