题目描述

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

输入

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

输出

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

样例输入

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

样例输出

6

提示

选出的子序列为2 4 3 3 5 3,相邻大小关系分别是< > = < >。

【题解】

    喜闻乐见的数据结构优化dp。看完了题,在演草纸上写了一句“动规吧?”,然后就把这句话放一边了。觉得二分应该能行,就写了个二分。怎么check呢?写了个dfs。后来跟wzz说这个事,大佬非常不理解地说:还不如直接深搜呢,白白地加个log。瞬间觉得好有道理啊,果然上午不知道干了些什么。

下午听讲题,自己连O(n^2)的转移方程都没写出来,简直了。正解思路很清奇,f[i]表示到i这一位最长的子序列长度,有了长度符号就定下来了。不等号按符号维护线段树,等号直接拿数组标记一下。线段树的下标是a[i]的权值,内容是f[i]的权值,这样区间查询满足不等号的最大值就非常快了。得出f[i]之后推出下一位的符号,更新相应的线段树或数组即可。

线段树是个好东西。上次方伯伯的玉米田用到了树状数组优化dp,这一次算是第二道数据结构优化dp。虽然在理论上来讲树状数组比线段树好打多了,可我始终还是更喜欢线段树。连续两天的dp题都是想过它是dp,但还是没按dp来做。学完一段时间以后dp能力下降得多了,想当初正在讲的时候也是不怕想正解的。原来以为自己不擅长数学和数据结构,现在看来dp也不是很行,集训要做的事还太多了啊。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int sj=;
char fh[sj];
int n,k,a[sj],f[sj],dh[],temp,jg,jd;
void bj(int &x,int y)
{
x=x>y?x:y;
}
struct Tree
{
int l,r,jz;
}ds[*],xs[*];
void bt1(int x,int y,int z)
{
ds[x].l=y;
ds[x].r=z;
if(y==z) return;
int mid=(y+z)>>;
bt1(x<<,y,mid);
bt1((x<<)|,mid+,z);
}
void bt2(int x,int y,int z)
{
xs[x].l=y;
xs[x].r=z;
if(y==z) return;
int mid=(y+z)>>;
bt2(x<<,y,mid);
bt2((x<<)|,mid+,z);
}
int query1(int x,int y,int z)
{
if(ds[x].l==y&&ds[x].r==z) return ds[x].jz;
int mid=(ds[x].l+ds[x].r)>>;
if(mid<y) return query1((x<<)|,y,z);
if(z<=mid) return query1(x<<,y,z);
return max(query1(x<<,y,mid),query1((x<<)|,mid+,z));
}
int query2(int x,int y,int z)
{
if(xs[x].l==y&&xs[x].r==z) return xs[x].jz;
int mid=(xs[x].l+xs[x].r)>>;
if(mid<y) return query2((x<<)|,y,z);
if(z<=mid) return query2(x<<,y,z);
return max(query2(x<<,y,mid),query2((x<<)|,mid+,z));
}
void update1(int x,int y,int z)
{
if(ds[x].l==ds[x].r&&ds[x].r==z)
{
ds[x].jz=y;
return;
}
int mid=(ds[x].l+ds[x].r)>>;
if(mid<z) update1((x<<)|,y,z);
if(z<=mid) update1(x<<,y,z);
ds[x].jz=max(ds[x<<].jz,ds[(x<<)|].jz);
}
void update2(int x,int y,int z)
{
if(xs[x].l==xs[x].r&&xs[x].r==z)
{
xs[x].jz=y;
return;
}
int mid=(xs[x].l+xs[x].r)>>;
if(mid<z) update2((x<<)|,y,z);
if(z<=mid) update2(x<<,y,z);
xs[x].jz=max(xs[x<<].jz,xs[(x<<)|].jz);
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
bj(jd,a[i]);
}
for(int i=;i<=k;i++) cin>>fh[i];
bt1(,,jd);
bt2(,,jd);
for(int i=;i<=n;i++)
{
if(dh[a[i]]+>f[i]) f[i]=dh[a[i]]+;
if(a[i]!=jd)
{
temp=query1(,a[i]+,jd);
if(temp+>f[i]) f[i]=temp+;
}
if(a[i]!=)
{
temp=query2(,,a[i]-);
if(temp+>f[i]) f[i]=temp+;
}
temp=f[i]%k;
if(!temp) temp=k;
if(fh[temp]=='=') dh[a[i]]=f[i];
if(fh[temp]=='>') update1(,f[i],a[i]);
if(fh[temp]=='<') update2(,f[i],a[i]);
bj(jg,f[i]);
}
printf("%d",jg);
return ;
}

Monotonicity 2[POI2010]的更多相关文章

  1. [补档][Poi2010]Monotonicity 2

    [Poi2010]Monotonicity 2 题目 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k]. 选出一个长度为L的子序列(不要求连续),要求这个子序列 ...

  2. BZOJ2090: [Poi2010]Monotonicity 2【线段树优化DP】

    BZOJ2090: [Poi2010]Monotonicity 2[线段树优化DP] Description 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k]. ...

  3. 【BZOJ2090/2089】[Poi2010]Monotonicity 2 动态规划+线段树

    [BZOJ2090/2089][Poi2010]Monotonicity Description 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k].选出一个长度 ...

  4. [Poi2010]Monotonicity 2 线段树

    这道题考试的时候先打了个dfs暴力.又打了个O(n²)的动规.然后竟然心血来潮拍了一下..明明知道过不去的...然后水了50分(20个测试点这么多啊啊啊啊). 因为它已经提前给你如果长度为i时下一位的 ...

  5. Poi2010 Monotonicity 2

    树状数组优化dp 可以证明最优解一定是通过之前的最优转移过来的,所以每一个点只需要保存以该节点为结尾的最长长度即可 对于不同符号,等于号维护数组,大于小于维护树状数组 #include<cstd ...

  6. #14 [BZOJ2090/2089] [Poi2010]Monotonicity 2/Monotonicity

    题解: 首先想到了标算..然后证明了一发是错的(事实证明很智障) 先说正确性比较显然的O(n^2)算法 令f[i][j]表示前i个物品,匹配到第j个括号,最大值是多少 g[i][j]表示前i个物品,匹 ...

  7. BZOJ2090 : [Poi2010]Monotonicity 2

    设f[i]表示以i为结尾的最长的合法序列的长度,=号直接维护,<号和>号用两棵树状数组维护即可,时间复杂度$O(n\log n)$. #include<cstdio> #def ...

  8. bzoj2089&2090: [Poi2010]Monotonicity

    双倍经验一眼题... f[i][1/2]表示以i结尾,当前符号应该是</>的最长上升子序列, 用BIT优化转移就好 =的话就不用说了吧= = #include<iostream> ...

  9. [BZOJ2090/2089] [Poi2010]Monotonicity 2/Monotonicity 树状数组优化dp

    这个dp乍看不科学,仔细一看更不科学,所以作为一个执着BOY,我决定要造数据卡死波兰人民,但是我造着造着就......证出来了......... 这个就是把 < > =分开讨论每次找到f[ ...

随机推荐

  1. 如何离线安装Visual Studio 2017

    1. 官方下载在线安装文件 vs_community.exe https://www.visualstudio.com/zh-hans/thank-you-downloading-visual-stu ...

  2. 《javascript高级程序设计》笔记三

    第三章 基本概念 任何语言的核心必然会描述这门语言最基本的工作原理.这部分内容对我们来说,读起来很乏味,甚至会产生困意,但这部分内容却是重要的!我有幸拜读<JavaScript高级程序设计> ...

  3. PHP运行出现Notice : Use of undefined constant

    这些是 PHP 的提示而非报错,PHP 本身不需要事先声明变量即可直接使用,但是对未声明变量会有提示.一般作为正式的网站会把提示关掉的,甚至连错误信息也被关掉 关闭 PHP 提示的方法 搜索php.i ...

  4. Kafka 源代码分析之FileMessageSet

    这里主要分析FileMessageSet类 这个类主要是管理log消息的内存对象和文件对象的类.源代码文件在log目录下.这个类被LogSegment类代理调用用来管理分片. 下面是完整代码.代码比较 ...

  5. 机器学习之分类问题实战(基于UCI Bank Marketing Dataset)

    导读: 分类问题是机器学习应用中的常见问题,而二分类问题是其中的典型,例如垃圾邮件的识别.本文基于UCI机器学习数据库中的银行营销数据集,从对数据集进行探索,数据预处理和特征工程,到学习模型的评估与选 ...

  6. c# 测试通过

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data; using S ...

  7. jquery.load问题

    简单Jquery--Ajax应用 作为一个新手,最近自己写了一个人主页,虽然性能不怎么样,但就出现的各种大的小的问题拿出来与大家分享分享. ----DanlV 描述 错误描述 自己不知道什么原因,直接 ...

  8. gulp总结

    安装 1.安装node 检测是否安装成功的方法,在命令行输入: node -v npm -v 显示版本号则安装成功 2.装cnmp一定要网络好一点 npm install cnpm -g --regi ...

  9. 单例设计模式 Single

    一些人总结出来用来解决特定问题的固定的解决方案. 解决一个类在内存中只存在一个对象,想要保证对象的唯一. 1 为了避免其他程序过多的建立该类对象.禁止其他程序建立该类对象. 2 为了其他程序可以访问该 ...

  10. Java基础语法<七> 对象与类

    笔记整理 来源于<Java核心技术卷 I > <Java编程思想> 1. 类之间的关系 依赖 users– a 是一种最明显的.最常见的关系.如果一个类的方法操作另一个类的对象 ...