【BZOJ2090/2089】[Poi2010]Monotonicity

Description

给出N个正整数a[1..N],再给出K个关系符号(>、<或=)s[1..k]。
选出一个长度为L的子序列(不要求连续),要求这个子序列的第i项和第i+1项的的大小关系为s[(i-1)mod K+1]。
求出L的最大值。

Input

第一行两个正整数,分别表示N和K (N, K <= 500,000)。
第二行给出N个正整数,第i个正整数表示a[i] (a[i] <= 10^6)。
第三行给出K个空格隔开关系符号(>、<或=),第i个表示s[i]。

Output

一个正整数,表示L的最大值。

Sample Input

7 3
2 4 3 1 3 5 3
< > =

Sample Output

6

题解:一开始没看到不要求连续,以为是一道KMP的裸题。。。

我们令f[i]表示第i个数最多能成为子序列的第f[i]项,所以当我们确定f[i]后,i的下一项和i的关系是确定的,所以我们考虑如何实现查询

我们根据三种关系,维护2个权值线段树和一个数组,分别对应>,<,=。=我就不说了,我们以<举例

如果f[i]对应的符号是<,那么我们将它放到<所对应的权值线段树中,权值线段树上v[i]位置的值就是f[i],然后在枚举到j的时候,就查询[1,v[j]-1]上f[]的最大值,再+1就能更新f[j]

#include <cstdio>
#include <iostream>
#include <cstring>
#define lson x<<1
#define rson x<<1|1
using namespace std;
int t[500010],v[500010],f[500010];
char str[5];
int n,m,nm,ans;
struct SAG
{
int sm[4000010];
void pushup(int x)
{
sm[x]=max(sm[lson],sm[rson]);
}
void updata(int l,int r,int x,int p,int v)
{
if(l==r)
{
sm[x]=v;
return ;
}
int mid=l+r>>1;
if(p<=mid) updata(l,mid,lson,p,v);
else updata(mid+1,r,rson,p,v);
pushup(x);
}
int query(int l,int r,int x,int a,int b)
{
if(a>b) return 0;
if(a<=l&&r<=b) return sm[x];
int mid=l+r>>1;
if(b<=mid) return query(l,mid,lson,a,b);
if(a>mid) return query(mid+1,r,rson,a,b);
return max(query(l,mid,lson,a,b),query(mid+1,r,rson,a,b));
}
}s[2];
int s2[1000010];
int max(int a,int b,int c)
{
return max(max(a,b),c);
}
int main()
{
scanf("%d%d",&n,&m);
int i,j;
for(i=1;i<=n;i++) scanf("%d",&v[i]),nm=max(v[i],nm);
for(i=1;i<=m;i++)
{
scanf("%s",str);
if(str[0]=='>') t[i]=0;
if(str[0]=='<') t[i]=1;
if(str[0]=='=') t[i]=2;
}
for(i=1;i<=n;i++)
{
f[i]=max(s[0].query(1,nm,1,v[i]+1,nm),s[1].query(1,nm,1,1,v[i]-1),s2[v[i]])+1;
ans=max(ans,f[i]);
j=t[(f[i]-1)%m+1];
if(j==2) s2[v[i]]=max(f[i],s2[v[i]]);
else s[j].updata(1,nm,1,v[i],f[i]);
}
printf("%d",ans);
return 0;
}

最新文章

  1. .net点选验证码实现思路分享
  2. 【BZOJ 1758】【WC 2010】重建计划 分数规划+点分治+单调队列
  3. java实现smtp邮件发送
  4. POJ 1658
  5. 《Java虚拟机原理图解》 1.2、class文件里的常量池
  6. android 36 线程通信
  7. poj 1458 Common Subsequence【LCS】
  8. 第一个MyBatis程序
  9. 动态根据checkbox 增加Dom
  10. iOS 静态库,动态库与 Framework 浅析
  11. phpcms通过URL传参
  12. The POM for * is invalid
  13. iOS逆向工程,(狗神)沙梓社大咖免费技术分享。
  14. 9.3、Libgdx手势检测
  15. woe_iv原理和python代码建模
  16. Mac电脑C语言开发的入门帖
  17. 十分钟了结MySQL information_schema
  18. Cforeach的详细用法--【转】
  19. my phone blackberry classic / passport / priv / keyone
  20. linux操作系统及命令Part 1

热门文章

  1. HTML-HTML5+CSS3权威指南阅读(一、HTML5与HTML4之间的区别)
  2. Grunt快速使用笔记
  3. HTTP Cache怎样计算Age
  4. navigate是Router类的一个方法,主要用来跳转路由。
  5. makefile之short函数
  6. csu-1328 近似回文词 和 最长回文字符串
  7. nyoj 460 项链 (区间dp)
  8. Android Screen Monitor
  9. PHP学习笔记(15)PDO数据库操作+AJAX无刷新技术删除用户
  10. android怎样写一个自己定义的dialog能够在Title的位置弹出来