CSU - 1551 Longest Increasing Subsequence Again —— 线段树/树状数组 + 前缀和&后缀和

题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1551


题意:

给出一段序列, 删除其中一段连续的子序列(或者不删), 使得剩下的序列的最长上升连续子序列最大。



题解:

1.对于要删除的的子序列而言,要么夹在答案序列中间,要么在外面(删与不删对答案都没影响)。所以总体而言,答案序列被分成左右两半。

2.用SL[i]记录从左边起以a[i]为结尾的最长上升连续子序列的长度, SR记录从右边起以a[i]为开始的最长上升连续子序列的长度。

3.枚举SR[i],用线段树找出最大的SL[x](x的下标小于i),即SL[x]和SR[x]构成一段完整的序列, 期间一直更新线段树。



学习之处:

1.线段树/树状数组的动态使用,即边查询边更新。 

类似的题: http://blog.csdn.net/DOLFAMINGO/article/details/65643894

2.RMQ/线段树/树状数组的静态使用,即build()之后值进行查询操作。

相关的题:http://blog.csdn.net/DOLFAMINGO/article/details/68953809       http://blog.csdn.net/dolfamingo/article/details/70306529



线段树:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <vector>
 7 #include <map>
 8 #include <set>
 9 #include <queue>
10 #include <sstream>
11 #include <algorithm>
12 using namespace std;
13 #define pb push_back
14 #define mp make_pair
15 #define ms(a, b)  memset((a), (b), sizeof(a))
16 #define eps 0.0000001
17 typedef long long LL;
18 const int INF = 2e9;
19 const LL LNF = 9e18;
20 const int mod = 1e9+7;
21 const int maxn = 10000+10;
22 
23 int a[maxn], SL[maxn], SR[maxn], MAX[maxn<<2];
24 int n;
25 
26 void update(int rt, int l, int r, int pos)
27 {
28     if(l==r)
29     {
30         MAX[rt] = max(MAX[rt], SL[pos]);
31         return;
32     }
33 
34     int mid = (l+r)>>1;
35     if(a[pos]<=mid) update(rt*2, l, mid, pos);
36     else update(rt*2+1 ,mid+1, r, pos);
37 
38     MAX[rt] = max(MAX[rt*2], MAX[rt*2+1]);
39 }
40 
41 int query(int rt, int l, int r, int x, int y)
42 {
43     if(x<=l && y>= r)
44         return MAX[rt];
45 
46     int mid = (l+r)>>1, ret = 0;
47     if(x<=mid) ret = max(ret, query(rt*2, l, mid, x, y));
48     if(y>=mid+1) ret = max(ret, query(rt*2+1, mid+1, r, x, y));
49     return ret;
50 }
51 
52 void solve()
53 {
54     for(int i = 1; i<=n; i++)
55         scanf("%d",&a[i]);
56 
57     SL[1] = SR[n] = 1;
58     for(int i = 2; i<=n; i++)
59         SL[i] = (a[i]>a[i-1]?SL[i-1]+1:1);
60     for(int i = n-1; i>0; i--)
61         SR[i] = (a[i]<a[i+1]?SR[i+1]+1:1);
62 
63     int ans = 0;
64     for(int i = 1; i<=n; i++)
65     {
66         int tmp = 0;
67         if(a[i]>1) tmp = query(1, 1, 10000, 1, a[i]-1);
68 
69         ans = max(ans,SR[i]+tmp);
70         update(1, 1, 10000, i);
71 
72     }
73     printf("%d\n",ans);
74 }
75 
76 int main()
77 {
78     while(scanf("%d",&n)!=EOF)
79     {
80         ms(SL,0);
81         ms(SR,0);
82         ms(MAX,0);
83         solve();
84     }
85 }
View Code


树状数组:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <vector>
 7 #include <map>
 8 #include <set>
 9 #include <queue>
10 #include <sstream>
11 #include <algorithm>
12 using namespace std;
13 #define pb push_back
14 #define mp make_pair
15 #define ms(a, b)  memset((a), (b), sizeof(a))
16 #define eps 0.0000001
17 typedef long long LL;
18 const int INF = 2e9;
19 const LL LNF = 9e18;
20 const int mod = 1e9+7;
21 const int maxn = 10000+10;
22 
23 int a[maxn], SL[maxn], SR[maxn], c[maxn];
24 int n;
25 
26 int lowbit(int x)
27 {
28     return x&(-x);
29 }
30 
31 void add(int x, int d)
32 {
33     while(x<maxn)
34     {
35         c[x] = max(c[x],d);
36         x += lowbit(x);
37     }
38 }
39 
40 int sumc(int x)
41 {
42     int s = 0;
43     while(x>0)
44     {
45         s = max(s,c[x]);
46         x -= lowbit(x);
47     }
48     return s;
49 }
50 
51 void solve()
52 {
53     for(int i = 1; i<=n; i++)
54         scanf("%d",&a[i]);
55 
56     SL[1] = SR[n] = 1;
57     for(int i = 2; i<=n; i++)
58         SL[i] = (a[i]>a[i-1]?SL[i-1]+1:1);
59     for(int i = n-1; i>0; i--)
60         SR[i] = (a[i]<a[i+1]?SR[i+1]+1:1);
61 
62     int ans = 0;
63     for(int i = 1; i<=n; i++)
64     {
65         int tmp = 0;
66         if(a[i]>1) tmp = sumc(a[i]-1);
67 
68         ans = max(ans,SR[i]+tmp);
69         add(a[i],SL[i]);
70 
71     }
72     printf("%d\n",ans);
73 }
74 
75 int main()
76 {
77     while(scanf("%d",&n)!=EOF)
78     {
79         ms(SL,0);
80         ms(SR,0);
81         ms(c,0);
82         solve();
83     }
84 }
View Code

 

 

 


 

posted on 2017-04-30 11:20  h_z_cong  阅读(332)  评论(0编辑  收藏  举报

导航