P3506 [POI2010]MOT-Monotonicity 2
题目
P3506 [POI2010]MOT-Monotonicity 2
第一次切掉没题解的题\(qwq\)
做法
首先确定\(a_i\)的位置后显然就能确定\(a_{i+1}\)的位置,建一棵权值线段树,维护\(<,=,>\)三种情况
考虑确定\(a_{i}\)的位置
在\([min,a_{i}-1]\)中找\(<\)的最大值
在\([a_{i}+1,max]\)中找\(>\)的最大值
找\([a_{i},a_{i}]\)的\(=\)的值(其实不用线段树,开个数组就能维护)
比较三个值,假定最大值为\(val\),则更新\([a_{i},a_{i}]\)中\(s[(val-1)\%k+1]\)的值(想一想为什么只更新一个符号的值就能保证正确性?)
这题的难点解决了,至于输出方案,如果你做多了这样的题自然能想到开个数组存每次的状态,然后再开个数组存前驱
代码写得比较乱,重载这些大家自己加吧
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef int LL;
const LL maxn=1500009;
inline LL Read(){
LL x(0),f(1); char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-1; c=getchar();
}
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-'0',c=getchar();
return x*f;
}
struct node{
LL mx,mxi,tot;
};
struct Tree{
node t[4];
LL son[2];
}tree[maxn];
LL nod;
node Query(LL now,LL l,LL r,LL lt,LL rt,LL opt){
if(!now||lt>rt)
return (node){0,0,0};
if(lt<=l&&rt>=r)
return tree[now].t[opt];
node ans=(node){0,0,0};
LL mid=(l+r)>>1;
if(lt<=mid)
ans=Query(tree[now].son[0],l,mid,lt,rt,opt);
if(rt>mid){
node tmp=Query(tree[now].son[1],mid+1,r,lt,rt,opt);
if(ans.mx<tmp.mx)
ans=tmp;
}
return ans;
}
inline void Update(LL now,LL opt){
LL son0(tree[now].son[0]),son1(tree[now].son[1]);
if(tree[son0].t[opt].mx>tree[son1].t[opt].mx)
tree[now].t[opt]=tree[son0].t[opt];
else
tree[now].t[opt]=tree[son1].t[opt];
}
inline void Change(LL &now,LL l,LL r,LL opt,LL goal,LL val,LL tot){
if(!now){
now=++nod;
if(l==r)
for(LL i=1;i<=3;++i)
tree[now].t[i]=(node){0,l,0};
}
if(l==r){
if(tree[now].t[opt].mx<val)
tree[now].t[opt].mx=val,
tree[now].t[opt].tot=tot;
return;
}
LL mid=(l+r)>>1;
if(goal<=mid)
Change(tree[now].son[0],l,mid,opt,goal,val,tot);
else
Change(tree[now].son[1],mid+1,r,opt,goal,val,tot);
Update(now,opt);
}
LL n,k,root,ans,last,_min,_max;
LL pre[maxn],a[maxn],c[maxn],ch[maxn],w[maxn];
void Write(LL now){
if(!now)
return;
Write(pre[now]);
printf("%d ",w[now]);
}
struct LS{
LL id,val;
}b[maxn];
inline bool cmp1(LS x,LS y){
return x.val<y.val;
}
int main(){
n=Read(),k=Read();
for(LL i=1;i<=n;++i)
b[i]=(LS){i,Read()},
c[i]=b[i].val;
sort(b+1,b+1+n,cmp1);
LL num(0);
for(LL i=1,last=-1;i<=n;++i){
if(last!=b[i].val)
last=b[i].val,
++num;
a[b[i].id]=num;
}
_min=1,_max=num;
for(LL i=1;i<=k;++i){
char c;
scanf(" %c",&c);
if(c=='<')
ch[i]=1;
else if(c=='>')
ch[i]=3;
else
ch[i]=2;
}
LL tot(0),last;
for(LL i=1;i<=n;++i){
node ans1=Query(root,_min,_max, _min,a[i]-1,1),
ans2=Query(root,_min,_max, a[i],a[i] ,2),
ans3=Query(root,_min,_max, a[i]+1,_max,3);
++ans1.mx,++ans2.mx,++ans3.mx;
if(ans1.mx<ans2.mx) ans1=ans2;
if(ans1.mx<ans3.mx) ans1=ans3;
LL sum(ans1.mx);
w[++tot]=c[i],
pre[tot]=ans1.tot,
Change(root,_min,_max,ch[(sum-1)%k+1],a[i],sum,tot);
if(sum>ans)
ans=sum,
last=tot;
}
printf("%d\n",ans);
Write(last);
return 0;
}/*
20 5
2 4 3 1 3 5 3 8 9 2 1 20 3 5 9 1 2 4 5 3
< > = < >
11
2 4 3 3 5 3 9 1 1 4 3
*/
P3506 [POI2010]MOT-Monotonicity 2的更多相关文章
- [补档][Poi2010]Monotonicity 2
[Poi2010]Monotonicity 2 题目 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k]. 选出一个长度为L的子序列(不要求连续),要求这个子序列 ...
- BZOJ2090: [Poi2010]Monotonicity 2【线段树优化DP】
BZOJ2090: [Poi2010]Monotonicity 2[线段树优化DP] Description 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k]. ...
- 【BZOJ2090/2089】[Poi2010]Monotonicity 2 动态规划+线段树
[BZOJ2090/2089][Poi2010]Monotonicity Description 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k].选出一个长度 ...
- [Poi2010]Monotonicity 2 线段树
这道题考试的时候先打了个dfs暴力.又打了个O(n²)的动规.然后竟然心血来潮拍了一下..明明知道过不去的...然后水了50分(20个测试点这么多啊啊啊啊). 因为它已经提前给你如果长度为i时下一位的 ...
- Poi2010 Monotonicity 2
树状数组优化dp 可以证明最优解一定是通过之前的最优转移过来的,所以每一个点只需要保存以该节点为结尾的最长长度即可 对于不同符号,等于号维护数组,大于小于维护树状数组 #include<cstd ...
- Monotonicity 2[POI2010]
题目描述 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k].选出一个长度为L的子序列(不要求连续),要求这个子序列的第i项和第i+1项的的大小关系为s[(i-1 ...
- #14 [BZOJ2090/2089] [Poi2010]Monotonicity 2/Monotonicity
题解: 首先想到了标算..然后证明了一发是错的(事实证明很智障) 先说正确性比较显然的O(n^2)算法 令f[i][j]表示前i个物品,匹配到第j个括号,最大值是多少 g[i][j]表示前i个物品,匹 ...
- BZOJ2090 : [Poi2010]Monotonicity 2
设f[i]表示以i为结尾的最长的合法序列的长度,=号直接维护,<号和>号用两棵树状数组维护即可,时间复杂度$O(n\log n)$. #include<cstdio> #def ...
- bzoj2089&2090: [Poi2010]Monotonicity
双倍经验一眼题... f[i][1/2]表示以i结尾,当前符号应该是</>的最长上升子序列, 用BIT优化转移就好 =的话就不用说了吧= = #include<iostream> ...
随机推荐
- 深入探析 Rational AppScan Standard Edition 新特性之 Glass Box 扫描
众所周知,Web 应用安全测试通常有黑盒安全测试和白盒安全测试两种方法.这两种方法孰优孰劣一直众议纷纷.广为公认的是,这两种测试方法有着良好地互补性,两种测试方法的结合是未来安全测试技术的发展趋势.G ...
- java之数字彩虹雨
© 版权声明:本文为博主原创文章,转载请注明出处 数字彩虹雨: 从上至下,随机出现一串字符串,以不同的速度运行到底部:类似于黑客帝国里面的场景 GitHub:https://github.com/Ta ...
- 初识C++之虚函数
1.什么是虚函数 在基类中用virtual关键字修饰.并在一个或多个派生类中被又一次定义的成员函数.使用方法格式为: virtual 函数返回类型 函数名(參数表) { 函数体 } 虚函数是实现多态性 ...
- unity3d WebPlayer版本号音效无声音问题
unity web player,其是一款浏览器执行unity3d游戏引擎公布的游戏的插件,和Flash Player非常像,安全无毒应该是你玩某款网页游戏安装的.假设以后不玩了就能够卸载 Unity ...
- Windows下静态库、动态库的创建和调用过程
静态库和动态库的使用包括两个方面,1是使用已有的库(调用过程),2是编写一个库供别人使用(创建过程).这里不讲述过多的原理,只说明如何编写,以及不正确编写时会遇见的问题. //注:本文先从简单到复杂, ...
- MySQL_常用SQL语句
1.按小时统计的语句 select concat(date_format(gmt_create, "%Y-%m-%d %k:00~"), hour(gmt_create)+1, & ...
- NOJ1167 丑陋数 想法题
题意 丑陋数n的意思是n的全部素数因子仅仅有2,3,5. 求出前1500个丑陋数. (第一个丑陋数是1) 思路 用一个数组维护全部的丑陋数. 一開始数组中仅仅有一个数就是1. 如今能够确定的丑陋数还有 ...
- MIC中offload语法总结
MIC中offload的用法如下: #pragma offload specifier [,specifier...]specifier可以填入的选项为:target 例:taget(mic:0)if ...
- ps -ef 和 aux 区别
Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信 ...
- windows下XAMPP安装php_memcache扩展
windows下XAMPP安装php_memcache扩展 首先下载phpmemcache,地址为: http://up.2cto.com/2012/0522/20120522094758371.ra ...