[Poi2010]Monotonicity 2

题目

给出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
< > =

OUTPUT

6

解题报告

考试时连最最最简单的DP都没想出来,就打了个DFS- -
正解:
我们先考虑只有一种符号的情况,比如说考虑<,那么不就变成了求最长上升子序列吗。
同样的,我们扩展至三种符号:
 for(int i=;i<=n;i++){
f[i]=;
for(int j=;j<=i-;j++){
int tmp(f[j]%k+);
if(op[tmp]=='='&&a[j]==a[i]&&f[j]+>f[i])
f[i]=f[j]+;
if(op[tmp]=='>'&&a[j]>a[i]&&f[j]+>f[i])
f[i]=f[j]+;
if(op[tmp]=='<'&&a[j]<a[i]&&f[j]+>f[i])
f[i]=f[j]+;
}
}
这就是最最最简单的DP,然而我们知道,这玩意是O(n²)的复杂度,显然会T,那么我们就需要优化一下了。
我们发现,转移时有O(n)的复杂度来找最大值,那么我们想,是否可以把这个过程优化呢?自然可以,我们的目的在于找到权值符合条件的最大f值,所以,我们需要一个新的东西来完成它:

权值线段树

这是一个神奇的数据结构- -,好吧,也不怎么神奇,它在这道题里是以权值为下标,存入该点最优解的一种线段树,它就可以完成这个伟大的任务啦。
我们需要3棵树(其实2棵也可以,相等的那个用数组模拟即可实现,只是我比较懒- -),每一棵树存以该符号为后面所接符号的权值的最优解(好绕啊- -),这样我们在找的时候,取出每棵树中符合权值条件的最优解,三解进行比较,选出最优以确定符号,继续转移并更新相应的线段树即可。
(我语文表达能力好弱啊)
 #include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
inline int read(){
int sum();
char ch(getchar());
for(;ch<''||ch>'';ch=getchar());
for(;ch>=''&&ch<='';sum=sum*+(ch^),ch=getchar());
return sum;
}
inline char init(){
char ch(getchar());
for(;ch!='='&&ch!='>'&&ch!='<';ch=getchar());
return ch;
}
inline int my_max(int a,int b){
return a>b?a:b;
}
int n,k;
int a[],op[];
int tr_d[],tr_x[],tr_e[];
int ad_d[],ad_x[],ad_e[];
inline void pushup_d(int i){
tr_d[i]=my_max(tr_d[i<<],tr_d[i<<|]);
}
inline void pushup_x(int i){
tr_x[i]=my_max(tr_x[i<<],tr_x[i<<|]);
}
inline void pushup_e(int i){
tr_e[i]=my_max(tr_e[i<<],tr_e[i<<|]);
}
inline void pushdown_d(int i){
if(ad_d[i]){
ad_d[i<<]=ad_d[i];
ad_d[i<<|]=ad_d[i];
tr_d[i<<]=ad_d[i];
tr_d[i<<|]=ad_d[i];
tr_d[i]=ad_d[i];
ad_d[i]=;
}
}
inline void pushdown_x(int i){
if(ad_x[i]){
ad_x[i<<]=ad_x[i];
ad_x[i<<|]=ad_x[i];
tr_x[i<<]=ad_x[i];
tr_x[i<<|]=ad_x[i];
tr_x[i]=ad_x[i];
ad_x[i]=;
}
}
inline void pushdown_e(int i){
if(ad_e[i]){
ad_e[i<<]=ad_e[i];
ad_e[i<<|]=ad_e[i];
tr_e[i<<]=ad_e[i];
tr_e[i<<|]=ad_e[i];
tr_e[i]=ad_e[i];
ad_e[i]=;
}
}
inline void update_d(int ll,int rr,int c,int l,int r,int i){
if(ll<=l&&r<=rr){
ad_d[i]=c;
tr_d[i]=c;
return;
}
pushdown_d(i);
int mid((l+r)>>);
if(ll<=mid)
update_d(ll,rr,c,l,mid,i<<);
if(rr>mid)
update_d(ll,rr,c,mid+,r,i<<|);
pushup_d(i);
}
inline void update_x(int ll,int rr,int c,int l,int r,int i){
if(ll<=l&&r<=rr){
ad_x[i]=c;
tr_x[i]=c;
return;
}
pushdown_x(i);
int mid((l+r)>>);
if(ll<=mid)
update_x(ll,rr,c,l,mid,i<<);
if(rr>mid)
update_x(ll,rr,c,mid+,r,i<<|);
pushup_x(i);
}
inline void update_e(int ll,int rr,int c,int l,int r,int i){
if(ll<=l&&r<=rr){
ad_e[i]=c;
tr_e[i]=c;
return;
}
pushdown_e(i);
int mid((l+r)>>);
if(ll<=mid)
update_e(ll,rr,c,l,mid,i<<);
if(rr>mid)
update_e(ll,rr,c,mid+,r,i<<|);
pushup_e(i);
}
inline int query_d(int ll,int rr,int l,int r,int i){
if(ll>rr)
return ;
if(ll<=l&&r<=rr)
return tr_d[i];
pushdown_d(i);
int mid((l+r)>>);
int ret();
if(ll<=mid)
ret=my_max(ret,query_d(ll,rr,l,mid,i<<));
if(rr>mid)
ret=my_max(ret,query_d(ll,rr,mid+,r,i<<|));
return ret;
}
inline int query_x(int ll,int rr,int l,int r,int i){
if(ll>rr)
return ;
if(ll<=l&&r<=rr)
return tr_x[i];
pushdown_x(i);
int mid((l+r)>>);
int ret();
if(ll<=mid)
ret=my_max(ret,query_x(ll,rr,l,mid,i<<));
if(rr>mid)
ret=my_max(ret,query_x(ll,rr,mid+,r,i<<|));
return ret;
}
inline int query_e(int ll,int rr,int l,int r,int i){
if(ll>rr)
return ;
if(ll<=l&&r<=rr)
return tr_e[i];
pushdown_e(i);
int mid((l+r)>>);
int ret();
if(ll<=mid)
ret=my_max(ret,query_e(ll,rr,l,mid,i<<));
if(rr>mid)
ret=my_max(ret,query_e(ll,rr,mid+,r,i<<|));
return ret;
}
int f[];
int mx();
int main(){
n=read(),k=read();
for(int i=;i<=n;i++)
a[i]=read(),mx=my_max(mx,a[i]);
for(int i=;i<=k;i++){
char ch(init());
if(ch=='>')
op[i]=;
if(ch=='<')
op[i]=;
if(ch=='=')
op[i]=;
}
f[]=;
if(op[]==)
update_d(a[],a[],f[],,mx,);
if(op[]==)
update_x(a[],a[],f[],,mx,);
if(op[]==)
update_e(a[],a[],f[],,mx,);
for(int i=;i<=n;i++){
int now(a[i]);
int ans_d(query_d(now+,mx,,mx,));
int ans_x(query_x(,now-,,mx,));
int ans_e(query_e(now,now,,mx,));
int ans(my_max(my_max(ans_d,ans_x),ans_e));
f[i]=ans+;
int o(op[ans%k+]);//cout<<i<<' '<<f[i]<<' '<<o<<endl;
if(o==)
update_d(now,now,f[i],,mx,);
if(o==)
update_x(now,now,f[i],,mx,);
if(o==)
update_e(now,now,f[i],,mx,);
}
int mxx();
for(int i=;i<=n;i++)
mxx=my_max(mxx,f[i]);
printf("%d",mxx);
}
写的极其丑- -,毕竟三颗线段树乱搞
凑合着看吧,其实理解了之后,一颗线段树,加不同的域,对传的参数进行处理,就可以达到三颗线段树的效果

[补档][Poi2010]Monotonicity 2的更多相关文章

  1. [补档]暑假集训D3总结

    考试 集训第一次考试,然而- -   总共四道题,两道打了DFS,一道暴力,一道~~输出样例~~乱搞,都是泪啊- - 目前只改了三道,回头改完那道题再上题解吧- - T2 [Poi2010]Monot ...

  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. STL 补档

    STL 补档 1.vector 作用:它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据. vector在C++标准模板库中的部分内容,它是 ...

  5. 图论补档——KM算法+稳定婚姻问题

    突然发现考前复习图论的时候直接把 KM 和 稳定婚姻 给跳了--emmm 结果现在刷训练指南就疯狂补档.QAQ. KM算法--二分图最大带权匹配 提出问题 (不严谨定义,理解即可) 二分图 定义:将点 ...

  6. [补档] 大假期集训Part.1

    新博客搭起来先补一发档... 那就从大假期集训第一部分说起好了QwQ 自己还是太菜掉回了2016级水平 day1: day1的时候来得有点晚(毕竟准高一)然后进机房发现早就开考了还没有给我题面于是搞了 ...

  7. 软件安装配置笔记(三)——ArcGIS系列产品安装与配置(补档)(附数据库连接及数据导入)

    在前两篇安装配置笔记之后,就忘记把其他安装配置笔记迁移过来了,真是失误失误!趁现在其他文档需要赶紧补上. 目录: 一.ArcMap 二.ArcMap连接数据库并导入数据 三.Arcgis Pro 四. ...

  8. 补档 Codeblocks下的文件标题栏(标签)显示方法

    可能在以下链接也能看到这篇文档 我知道很多人都不知道这个到底叫啥,还不如直接一点: 文件标题栏 就是如下的效果. 解决办法: 在左上角第三个view下,打开后取消Hide editor tabs 选项 ...

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

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

随机推荐

  1. ECSHOP购物车页面显示商品简单描述

    1.这里说的商品简单描述,不是商品的详细信息,而是后台编辑商品时在“其他信息”标签栏填写的那个“商品简单描述”,即goods_brief字段 2.修改lib_order.php文件的get_cart_ ...

  2. 使用websocket-sharp来创建c#版本的websocket服务

    当前有一个需求,需要网页端调用扫描仪,javascript不具备调用能力,因此需要在机器上提供一个ws服务给前端网页调用扫描仪.而扫描仪有一个c#版本的API,因此需要寻找一个c#的websocket ...

  3. react-native —— 在Mac上配置React Native Android开发环境排坑总结

    配置React Native Android开发环境总结 1.卸载Android Studio,在终端(terminal)执行以下命令: rm -Rf /Applications/Android\ S ...

  4. Python进阶-继承中的MRO与super

    Python进阶-继承中的MRO与super 写在前面 如非特别说明,下文均基于Python3 摘要 本文讲述Python继承关系中如何通过super()调用"父类"方法,supe ...

  5. linux 升级yum对应的python

    这里记录一下linux 系统升级python对yum带来影响的解决办法 很多人在使用linux系统执行python任务的时候需要升级linux系统自带的python到高级版本.具体如何升级python ...

  6. Example003通过按钮创建窗口

    <!--实例003通过按钮创建窗口--> <head> <meta charset="UTF-8"> </head> <for ...

  7. 复写equals、hashCode和toString方法

    equals.hashCode和toString 这三个方法都是object类的方法,由于所有的类都是继承这个类,所以每一个类都有这三个方法. 1.复写equals方法 原则: 首先,两个实例是相同的 ...

  8. JavaScript学习笔记(散)——继承、构造函数super

    构造函数中的super 今天看<JavaScript设计模式与开发实践>时,在书中看到一段代码出现super语句,第一次看到这个关键字,所以上网查了下它的作用,发现这个关键字是来自java ...

  9. Vijos 1004 伊甸园日历游戏 博弈

    描述 Adam和Eve玩一个游戏,他们先从1900.1.1到2001.11.4这个日期之间随意抽取一个日期出来.然后他们轮流对这个日期进行操作: 1 : 把日期的天数加1,例如1900.1.1变到19 ...

  10. C#深入学习 ----多线程学习(一)第一天学习

    学习最好的方法就是总结,并写下来,能让别人看懂,自己肯定是掌握了的. 针对软件开发,一直停留在能做的层次,今天得到大牛指点,觉得有必要对这门技术深入学习. 翻阅园内各大神的文章,收益匪浅,在这里做下总 ...