首页 > 代码库 > UVALive 4976 Defense Lines ——(LIS变形)

UVALive 4976 Defense Lines ——(LIS变形)

  题意:给出序列,能够从这序列中删去连续的一段,问剩下的序列中的最长的严格上升子串的长度是多少。

  这题颇有点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 }

 

UVALive 4976 Defense Lines ——(LIS变形)