机房的人问我树状数组怎么做这题......
树状数组维护$len, num$表示$LIS$的长度和数量即可
复杂度$O(n log n)$
注:$O(n log n)$二分+单调栈才是真神仙
具体看代码
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; extern inline char gc() { static char RR[23456], *S = RR + 23333, *T = RR + 23333; if(S == T) fread(RR, 1, 23333, stdin), S = RR; return *S ++; } inline int read() { int p = 0, w = 1; char c = gc(); while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); } while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc(); return p * w; } #define mod 1000000007 #define ri register int #define sid 50050 int n, cnp, H[sid], a[sid]; struct aha { int len, num; } t[sid], f[sid]; void upd(aha &x, aha y) { if(x.len > y.len) return; if(x.len < y.len) x = y; else x.num += y.num, x.num %= mod; } aha qry(int x) { aha ret = { 0, 1 }; for(ri i = x; i; i -= i &(-i)) upd(ret, t[i]); return ret; } aha add(int x, aha v) { for(ri i = x; i <= cnp; i += i & (-i)) upd(t[i], v); } int main() { n = read(); for(ri i = 1; i <= n; i ++) a[i] = H[i] = read(); sort(H + 1, H + n + 1); cnp = unique(H + 1, H + n + 1) - H - 1; for(ri i = 1; i <= n; i ++) a[i] = lower_bound(H + 1, H + cnp + 1, a[i]) - H; for(ri i = 1; i <= n; i ++) { f[i] = qry(a[i] - 1); f[i].len ++; add(a[i], f[i]); } aha ans = { 0, 0 }; for(ri i = 1; i <= n; i ++) upd(ans, f[i]); printf("%d ", ans.num); return 0; }