此题紫书上面有详细分析,关键是运用Set优化实现O(nlgn)复杂度
AC代码:
#include<cstdio> #include<set> #include<algorithm> using namespace std; const int maxn = 2e5+5; int num[maxn], h[maxn], g[maxn]; //g[i] - num[i] is the Last //h[i] - num[i] is the First struct node{ int val, lenth; node(){} node(int val, int lenth):val(val), lenth(lenth){} bool operator < (const node &p) const { return val < p.val; } }; #define It set<node>::iterator int solve(int n){ set<node> Set; int ans = g[0]; Set.insert(node(num[0], g[0])); for(int i = 1; i < n; ++i){ node c(num[i], g[i]); It it = Set.lower_bound(c); //得到迭代器 bool ok = 1; //keep if(it != Set.begin()){ node pre = *(--it); ans = max(ans, pre.lenth + h[i]); if(pre.lenth >= c.lenth) ok = 0; } if(ok){ //intsert C Set.erase(c); Set.insert(c); it = Set.find(c); it++; while(it != Set.end() && it->lenth <= c.lenth) Set.erase(it++); } } return ans; } int main(){ int T; scanf("%d", &T); while(T--){ int n; scanf("%d", &n); for(int i = 0; i < n; ++i) scanf("%d", &num[i]); // 处理g[i] g[0] = 1; for(int i = 1; i < n; ++i) { if(num[i] > num[i-1]) g[i] = g[i-1] + 1; else g[i] = 1; } // 处理h[i] h[n-1]=1; for(int i = n-2; i >= 0; --i) { if(num[i] < num[i+1]) h[i] = h[i+1] + 1; else h[i] = 1; } printf("%d\n",solve(n)); } return 0; }
如有不当之处欢迎指出!