可以称为,模拟题、、、
我们发现,由于是从小到大插入的,所以后插入的数不会影响先插入的数的ans
于是只要对最后的序列求一次LIS即可。
问题就集中在如何求最后的序列:
方法一:treap无脑模拟插入操作
就当是treap的练手吧。。。结果RE了一版,后来突然一拍脑袋发现。。bz上不让调用time()函数。。。各种蛋疼
1 /************************************************************** 2 Problem: 3173 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:660 ms 7 Memory:3936 kb 8 ****************************************************************/ 9 10 #include <cstdlib> 11 #include <cstdio> 12 #include <cstring> 13 #include <algorithm> 14 15 using namespace std; 16 const int N = 100005; 17 const int inf = 1e9; 18 19 struct treap_node { 20 treap_node *son[2]; 21 int pri, sz, v; 22 } *null, *root, mempool[N], *cnt_treap = mempool; 23 24 int n, cnt, len; 25 int a[N], ans[N], mn[N]; 26 27 int read() { 28 int x = 0; 29 char ch = getchar(); 30 while (ch < '0' || '9' < ch) 31 ch = getchar(); 32 while ('0' <= ch && ch <= '9') 33 (x *= 10) += ch - '0', ch = getchar(); 34 return x; 35 } 36 37 #define Ls (p -> son[0]) 38 #define Rs (p -> son[1]) 39 #define Pri (p -> pri) 40 #define Sz (p -> sz) 41 #define V (p -> v) 42 inline void treap_update(treap_node *p) { 43 Sz = Ls -> sz + Rs -> sz + 1; 44 } 45 46 void treap_rotate(treap_node *&p, int ch) { 47 treap_node *tmp = p -> son[ch]; 48 p -> son[ch] = tmp -> son[!ch]; 49 tmp -> son[!ch] = p; 50 treap_update(p), treap_update(tmp); 51 p = tmp; 52 } 53 54 void treap_insert(treap_node *&p, int rank) { 55 if (p == null) { 56 p = ++cnt_treap, Ls = Rs = null; 57 Pri = rand(), Sz = 1, V = cnt; 58 return; 59 } 60 ++Sz; 61 if (Ls -> sz < rank) { 62 treap_insert(Rs, rank - Ls -> sz - 1); 63 if (Rs -> pri > Pri) treap_rotate(p, 1); 64 } else { 65 treap_insert(Ls, rank); 66 if (Ls -> pri > Pri) treap_rotate(p, 0); 67 } 68 } 69 70 void get_seq(treap_node *p) { 71 if (p == null) return; 72 get_seq(Ls); 73 a[++cnt] = V; 74 get_seq(Rs); 75 } 76 #undef Ls 77 #undef Rs 78 #undef Pri 79 #undef Sz 80 #undef Num 81 82 int main() { 83 int i, t; 84 n = read(); 85 null = ++cnt_treap; 86 null -> son[0] = null -> son[1] = null; 87 null -> pri = null -> sz = null -> v = 0; 88 root = null; 89 for (cnt = 1; cnt <= n; ++cnt) 90 treap_insert(root, read()); 91 cnt = 0; 92 get_seq(root); 93 memset(mn, 127, sizeof(mn)); 94 for (mn[0] = -inf, i = 1; i <= n; ++i) { 95 t = upper_bound(mn, mn + len + 1, a[i]) - mn; 96 if (mn[t - 1] <= a[i]) { 97 mn[t] = min(mn[t], a[i]); 98 ans[a[i]] = t; 99 len = max(t, len); 100 } 101 } 102 for (i = 1; i <= n; ++i) 103 printf("%d\n", ans[i] = max(ans[i], ans[i - 1])); 104 return 0; 105 }