BZOJ2090: [Poi2010]Monotonicity 2

n<=500000的序列和m<=500000的符号串,求最长的子序列,满足选中的数中第i个数和第i+1个数满足符号关系Si。

最长xx子序列--DP+树状数组。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<stdlib.h>
 5 //#include<iostream>
 6 using namespace std;
 7  
 8 int n,m;
 9 #define maxn 1000011
10 int a[maxn];char s[maxn],tmp[4];
11  
12 struct BIT
13 {
14     int a[maxn],n;
15     void clear(int m) {n=m;memset(a,0,sizeof(a));}
16     void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]=max(a[x],v);}
17     int query(int x) {int ans=0;for (;x;x-=x&-x) ans=max(ans,a[x]);return ans;}
18 }tp,ts;
19 int cnt[maxn];
20  
21 int f[maxn];
22 int main()
23 {
24     scanf("%d%d",&n,&m);
25     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
26     for (int i=1;i<=m;i++)
27     {
28         scanf("%s",tmp);
29         s[i]=tmp[0];
30     }
31     for (int i=m+1;i<=n;i++) s[i]=s[i-m];m=n;
32     int ppp=1000001;
33     tp.clear(ppp);ts.clear(ppp);
34     int ans=0;
35     for (int i=1;i<=n;i++)
36     {
37         f[i]=tp.query(a[i]-1)+1;
38         f[i]=max(f[i],ts.query(ppp-a[i])+1);
39         f[i]=max(f[i],cnt[a[i]]+1);
40         if (s[f[i]]=='<') tp.add(a[i],f[i]);
41         else if (s[f[i]]=='>') ts.add(ppp-a[i]+1,f[i]);
42         else cnt[a[i]]=max(cnt[a[i]],f[i]);
43         ans=max(ans,f[i]);
44     }
45     printf("%d\n",ans);
46     return 0;
47 }
View Code

 

posted @ 2017-11-28 07:07  Blue233333  阅读(143)  评论(0编辑  收藏  举报