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 }