题意:给出序列,能够从这序列中删去连续的一段,问剩下的序列中的最长的严格上升子串的长度是多少。
这题颇有点LIS的味道。因为具体做法就是维护一个单调的集合,然后xjbg一下即可。具体的见代码吧:
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 using namespace std; 5 const int N = 2e5 + 5; 6 7 int T,n,top,back; 8 int a[N]; 9 int R[N]; 10 int s[N]; 11 12 int find(int val) 13 { 14 int l = 0, r = top; 15 int ans = -1; 16 while(l <= r) 17 { 18 int mid = l + r >> 1; 19 if(s[mid] < val) ans = mid, l = mid + 1; 20 else r = mid - 1; 21 } 22 return ans; 23 } 24 25 void solve() 26 { 27 back = 1, top = 1; 28 s[top] = a[1]; 29 int ans = 1; 30 for(int i=2;i<=n;i++) 31 { 32 ans = max(ans, find(a[i]) + R[i]); 33 if(a[i] > a[i-1]) back++; 34 else back = 1; 35 if(back > top) s[++top] = a[i]; 36 else s[back] = min(s[back], a[i]); 37 } 38 printf("%d\n",ans); 39 } 40 41 int main() 42 { 43 scanf("%d",&T); 44 while(T--) 45 { 46 scanf("%d",&n); 47 for(int i=1;i<=n;i++) scanf("%d",a+i); 48 R[n] = 1; 49 for(int i=n-1;i>=1;i--) R[i] = a[i] < a[i+1] ? R[i+1] + 1 : 1; 50 solve(); 51 } 52 return 0; 53 }
时间: 2024-10-27 17:01:29