乱写了一个dp,结果A掉了。。
表示以
结尾的最长长度。
首先
。
然后
满足
还有下面这几条的任意一条
这样写能A,貌似是有正确性保证的。
可以写线段树或者树状数组。
线段树
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=500005;
int n,k,ans,a[N],h[N],b[N],f[N];
char str[5];
struct SegmentTree{
int maxn[N*4];
void update(int o,int l,int r,int k,int v){
if(l==r){
maxn[o]=v;
return;
}
int mid=(l+r)/2;
if(k<=mid){
update(o*2,l,mid,k,v);
}else{
update(o*2+1,mid+1,r,k,v);
}
maxn[o]=max(maxn[o*2],maxn[o*2+1]);
}
int query(int o,int l,int r,int L,int R){
if(L>R){
return 0;
}
if(L==l&&R==r){
return maxn[o];
}
int mid=(l+r)/2;
if(R<=mid){
return query(o*2,l,mid,L,R);
}else if(L>mid){
return query(o*2+1,mid+1,r,L,R);
}else{
return max(query(o*2,l,mid,L,mid),query(o*2+1,mid+1,r,mid+1,R));
}
}
}t1,t2,t3;
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
h[++h[0]]=a[i];
}
sort(h+1,h+h[0]+1);
h[0]=unique(h+1,h+h[0]+1)-h-1;
for(int i=1;i<=n;i++){
a[i]=lower_bound(h+1,h+h[0]+1,a[i])-h;
}
for(int i=1;i<=k;i++){
scanf("%s",str);
switch(str[0]){
case '<':b[i]=0;break;
case '=':b[i]=1;break;
case '>':b[i]=2;break;
}
}
for(int i=1;i<=n;i++){
f[i]=1;
f[i]=max(f[i],t1.query(1,1,h[0],1,a[i]-1)+1);
f[i]=max(f[i],t2.query(1,1,h[0],a[i],a[i])+1);
f[i]=max(f[i],t3.query(1,1,h[0],a[i]+1,h[0])+1);
if(b[(f[i]-1)%k+1]==0){
t1.update(1,1,h[0],a[i],f[i]);
}else if(b[(f[i]-1)%k+1]==1){
t2.update(1,1,h[0],a[i],f[i]);
}else{
t3.update(1,1,h[0],a[i],f[i]);
}
ans=max(ans,f[i]);
}
printf("%d\n",ans);
return 0;
}
树状数组
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=500005;
int n,k,ans,a[N],h[N],b[N],f[N],gao[N];
char str[5];
struct BinaryIndexTree{
int c[N];
void update(int i,int x){
while(i<=h[0]){
c[i]=max(c[i],x);
i+=i&(-i);
}
}
int query(int i){
int res=0;
while(i){
res=max(res,c[i]);
i-=i&(-i);
}
return res;
}
}t1,t2;
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
h[++h[0]]=a[i];
}
sort(h+1,h+h[0]+1);
h[0]=unique(h+1,h+h[0]+1)-h-1;
for(int i=1;i<=n;i++){
a[i]=lower_bound(h+1,h+h[0]+1,a[i])-h;
}
for(int i=1;i<=k;i++){
scanf("%s",str);
switch(str[0]){
case '<':b[i]=0;break;
case '=':b[i]=1;break;
case '>':b[i]=2;break;
}
}
for(int i=1;i<=n;i++){
f[i]=max(f[i],t1.query(a[i]-1)+1);
f[i]=max(f[i],gao[a[i]]+1);
f[i]=max(f[i],t2.query(h[0]-a[i])+1);
if(b[(f[i]-1)%k+1]==0){
t1.update(a[i],f[i]);
}else if(b[(f[i]-1)%k+1]==1){
gao[a[i]]=max(gao[a[i]],f[i]);
}else{
t2.update(h[0]-a[i]+1,f[i]);
}
ans=max(ans,f[i]);
}
printf("%d\n",ans);
return 0;
}