[Poi2010]Monotonicity 2
f[i]:前i长度的最长子序列 O(n^2)的暴力转移: for(int i=1;i<=n;++i) for(int j=1;j<i;++j) { int temp=(f[j]-1)%k+1; if(a[j]<a[i]&&s[temp]=='<')ans=maxn(ans,f[j]+1); else if(a[j]>a[i]&&s[temp]=='>')ans=maxn(ans,f[j]+1); else if(a[j]==a[i]&&s[temp]=='=')ans=maxn(ans,f[j]+1); } 应该都会写 O(n*logn): 用树状数组或线段树分别维护前i个 > < = 的最大值 用树状数组要注意边界.....
1 #include<cstdio> 2 #include<cstring> 3 #include<ctime> 4 #include<queue> 5 #include<algorithm> 6 #include<iostream> 7 #define dd double 8 #define mem(a,b) memset(a,b,sizeof(a)) 9 using namespace std; 10 const int N=2000005; 11 const int Max=2000002; 12 int maxn(int a,int b){return a>b?a:b;} 13 int minn(int a,int b){return a<b?a:b;} 14 int readchar() 15 { 16 char q=getchar(); 17 while(q!='<'&&q!='='&&q!='>')q=getchar(); 18 return q; 19 } 20 21 int c[N],c1[N],c2[N]; 22 void add(int pos,int val){c[pos]=maxn(c[pos],val);} 23 int qq(int pos){return c[pos];} 24 25 void add1(int pos,int val) 26 { 27 for(int i=pos+1;i<=Max;i+=(i&(-i))) 28 c1[i]=maxn(c1[i],val); 29 } 30 int qq1(int pos) 31 { 32 int ans=0; 33 for(int i=pos;i>0;i-=(i&(-i))) 34 ans=maxn(ans,c1[i]); 35 return ans; 36 } 37 38 void add2(int pos,int val) 39 { 40 for(int i=pos-1;i>0;i-=(i&(-i))) 41 c2[i]=maxn(c2[i],val); 42 } 43 int qq2(int pos) 44 { 45 int ans=0; 46 for(int i=pos;i<=Max;i+=(i&(-i))) 47 ans=maxn(ans,c2[i]); 48 return ans; 49 } 50 51 int n,k,ans; 52 int a[N],dui[N]; 53 char s[N]; 54 int f[N]; 55 56 void ADD(int pos,int val) 57 { 58 if(s[dui[val]]=='<')add1(pos,val); 59 else if(s[dui[val]]=='>')add2(pos,val); 60 else add(pos,val); 61 } 62 63 int main(){ 64 //freopen("mot17.in","r",stdin); 65 //freopen("mot.out","w",stdout); 66 scanf("%d%d",&n,&k); 67 for(int i=1;i<=n;++i) 68 { 69 scanf("%d",&a[i]); 70 dui[i]=(i-1)%k+1; 71 } 72 for(int i=1;i<=k;++i)s[i]=readchar(); 73 74 ADD(a[1],1); 75 int q,q1,q2; 76 for(int i=2;i<=n;++i) 77 { 78 q=qq(a[i]);q1=qq1(a[i]);q2=qq2(a[i]); 79 //printf("i=%d q=%d q1=%d q2=%d\n",i,q,q1,q2); 80 ADD(a[i],q+1); 81 ADD(a[i],q1+1); 82 ADD(a[i],q2+1); 83 ans=maxn(ans,maxn(q,maxn(q1,q2))+1); 84 } 85 86 /*for(int i=1;i<=n;++i) 87 printf("%d ",f[i]); 88 printf("\n");*/ 89 printf("%d",ans); 90 //while(1); 91 return 0; 92 }