题目描述

佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他。玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一个值发生变化。现在佳媛姐姐已经研究出了所有变化的可能性,她想请教你,能否选出一个子序列,使得在任意一种变化中,这个子序列都是不降的?请你告诉她这个子序列的最长长度即可 。

注意:每种变化最多只有一个值发生变化。在样例输入1中,所有的变化是:

  1. 1 2 3
  2. 2 2 3
  3. 1 3 3
  4. 1 1 3
  5. 1 2 4

选择子序列为原序列,即在任意一种变化中均为不降子序列在样例输入2中,所有的变化是:

  1. 3 3 3
  2. 3 2 3

选择子序列为第一个元素和第三个元素,或者第二个元素和第三个元素,均可满足要

输入输出格式

输入格式:

输入的第一行有两个正整数n, m,分别表示序列的长度和变化的个数。接下来一行有n个数,表示这个数列原始的状态。接下来m行,每行有2个数x, y,表示数列的第x项可以变化成y这个值。1 <= x <= n。

输出格式:

输出一个整数,表示对应的答案

输入输出样例

输入样例#1: 复制

  1. 3 4
  2. 1 2 3
  3. 1 2
  4. 2 3
  5. 2 1
  6. 3 4
输出样例#1: 复制

  1. 3

说明

对于20%数据所有数字均为正整数,且小于等于300

对于50%数据所有数字均为正整数,且小于等于3,000

对于100%数据所有数字均为正整数,且小于等于100,000

这道题是DP应该不难看出来。

$dp[i]$表示选择$i$以后所能形成的满足条件的子序列的最大值

转移的时候枚举前面的点$(j)$。

设$MX[i]$表示$i$号位置能变成的最大值,$MI[i]$表示$i$号位置能变成的最小值,$a$为原序列

这样转移的时候会有两个限制条件

$a[i]>=MX[j]$ && $MI[i]>=a[j]$

这很明显是个二维偏序问题嘛,用CDQ树套树什么的都可以搞。

树套树的话,将$a$抽象为$x$轴,将$MX$抽象为$y$轴

转移的时候我们实际是在左下角为$(0,0)$,右上角为$MI[i],a[i]$的矩阵中查最大值

每次转移对答案的贡献的话实际上只是改变了$a[i],mx[i]$的值

然后就能很自然的想到树套树了,线段树套线段树或者树状数组套线段树都可以搞

后者常数小一些

线段树的数组一定要开的足够大!!!!

  1. #include<cstdio>
  2. #include<cmath>
  3. #include<algorithm>
  4. using namespace std;
  5. const int MAXN=*1e6+;
  6. const int MAXNN=1e5+;
  7. const int INF=1e8+;
  8. inline int read()
  9. {
  10. char c=getchar();int x=,f=;
  11. while(c<''||c>''){if(c=='-')f=-;c=getchar();}
  12. while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
  13. return x*f;
  14. }
  15. int root[MAXN],N,M,MX[MAXNN],MI[MAXNN],a[MAXNN];
  16. struct S
  17. {
  18. struct node
  19. {
  20. int ls,rs,mx;
  21. }T[MAXN];
  22. int tot;
  23. int query(int now,int ll,int rr,int pos)
  24. {
  25. if(ll==rr)
  26. return T[now].mx;
  27. int mid=ll+rr>>;
  28. if(pos<=mid)
  29. return query(T[now].ls,ll,mid,pos);
  30. else
  31. return max( T[T[now].ls].mx , query(T[now].rs,mid+,rr,pos));
  32. }
  33. void change(int &now,int ll,int rr,int pos,int val)
  34. {
  35. if(!now) now=++tot;
  36. T[now].mx=max(T[now].mx,val);
  37. if(ll==rr) return ;
  38. int mid=ll+rr>>;
  39. if(pos<=mid) change(T[now].ls,ll,mid,pos,val);
  40. else change(T[now].rs,mid+,rr,pos,val);
  41. }
  42. }tree;
  43. struct B
  44. {
  45. int N;
  46. int Tree[MAXNN];
  47. int lowbit(int p) {return p&(-p);}
  48. int Query(int k,int val)
  49. {
  50. int ans=;
  51. while(k)
  52. {
  53. ans=max(ans,tree.query(root[k],,N,val));
  54. k-=lowbit(k);
  55. }
  56. return ans;
  57. }
  58. void Change(int k,int pos,int val)
  59. {
  60. while(k<=N)
  61. {
  62. tree.change(root[k],,N,pos,val);
  63. k+=lowbit(k);
  64. }
  65. }
  66. }BIT;
  67. int main()
  68. {
  69. //freopen("heoi2016_seq.in","r",stdin);
  70. //freopen("heoi2016_seq.out","w",stdout);
  71. N=read();M=read();
  72. for(int i=;i<=N;i++) MX[i]=MI[i]=a[i]=read();
  73. for(int i=;i<=M;i++)
  74. {
  75. int x=read(),y=read();
  76. MX[x]=max(MX[x],y);BIT.N=max(BIT.N,MX[x]);
  77. MI[x]=min(MI[x],y);
  78. }
  79. int ans=;
  80. for(int i=;i<=N;i++)
  81. {
  82. int now=BIT.Query(MI[i],a[i])+;
  83. BIT.Change(a[i],MX[i],now);
  84. ans=max(ans,now);
  85. }
  86. printf("%d",ans);
  87. return ;
  88. }

洛谷P4093 [HEOI2016/TJOI2016]序列的更多相关文章

  1. 洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP

    洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他. 玩具上有一个数列,数列中某些项的值可能会 ...

  2. 洛谷 P4093 [HEOI2016/TJOI2016]序列 解题报告

    P4093 [HEOI2016/TJOI2016]序列 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一 ...

  3. BZOJ4553/洛谷P4093 [HEOI2016/TJOI2016]序列 动态规划 分治

    原文链接http://www.cnblogs.com/zhouzhendong/p/8672434.html 题目传送门 - BZOJ4553 题目传送门 - 洛谷P4093 题解 设$Li$表示第$ ...

  4. 洛谷 P4093 [HEOI2016/TJOI2016]序列(Cdq+dp)

    题面 luogu 题解 \(Cdq分治+dp\) \(mx[i],mn[i]\)分别表示第\(i\)位最大,最小能取到多少 那么有 \(j < i\) \(mx[j] \le a[i]\) \( ...

  5. 洛谷 P2824 [HEOI2016/TJOI2016]排序 解题报告

    P2824 [HEOI2016/TJOI2016]排序 题意: 有一个长度为\(n\)的1-n的排列\(m\)次操作 \((0,l,r)\)表示序列从\(l\)到\(r\)降序 \((1,l,r)\) ...

  6. 洛谷 P4091 [HEOI2016/TJOI2016]求和 解题报告

    P4091 [HEOI2016/TJOI2016]求和 题目描述 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: \[ f(n)=\sum_{i=0}^n\ ...

  7. Luogu P4093 [HEOI2016/TJOI2016]序列 dp套CDQ

    题面 好久没写博客了..最近新学了CDQ...于是就来发一发一道CDQ的练习题 看上去就是可以dp的样子. 设\(dp_{i}\)为以i结尾的最长不下降序列. 易得:\(dp_{i}\)=\(max( ...

  8. 洛谷P2824 [HEOI2016/TJOI2016]排序(线段树)

    传送门 这题的思路好清奇 因为只有一次查询,我们考虑二分这个值为多少 将原序列转化为一个$01$序列,如果原序列上的值大于$mid$则为$1$否则为$0$ 那么排序就可以用线段树优化,设该区间内$1$ ...

  9. 洛谷 P2824 [HEOI2016/TJOI2016]排序 (线段树合并)

    (另外:题解中有一种思路很高妙而且看上去可以适用一些其他情况的离线方法) 线段树合并&复杂度的简单说明:https://blog.csdn.net/zawedx/article/details ...

随机推荐

  1. 05003_Linux的基本命令

    1.目录结构 Linux的目录结构:Linux各目录及每个目录的详细介绍 链接:Linux各目录及每个目录的详细介绍 密码:84ab 2.LInux的基本命令 (1)目录切换命令 ①root是超级管理 ...

  2. Qt之QDesktopServices

    简述 QDesktopServices类提供的函数用于访问常见的桌面服务. 许多桌面环境都会提供一系列服务,可以通过应用程序来执行常见任务,如:以用户应用程序首选项的方式,打开一个网页. 此类包含为服 ...

  3. scratchIDE使用说明

    scratchIDE使用说明

  4. Hdoj 1176 免费馅饼 【动态规划】

    免费馅饼 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  5. IIC总线协议基础1

    文档类别 文档标识 IIC总线协议基础1 当前版本号 V0.2 作    者 Louis 完毕时间 2015-05-27 IIC总线协议基础1 IIC总线协议基础1. 1.            II ...

  6. UVA 11426 GCD - Extreme (II) (数论|欧拉函数)

    题意:求sum(gcd(i,j),1<=i<j<=n). 思路:首先能够看出能够递推求出ans[n],由于ans[n-1]+f(n),当中f(n)表示小于n的数与n的gcd之和 问题 ...

  7. nj06---包

    二.创建包 1.包的概念 包是在模块基础上更深一步的抽象,Node.js的包类似于C/C++的函数库或者java的类库,它讲某个独立的功能封装起来,用于发布.更新.依赖管理的版本控制.开发了npm来解 ...

  8. 安卓第一课:android studio 的环境搭建与真机运行以及遇到的问题

    AS的下载: https://developer.android.com/studio/index.html AS的安装: android studio, sdk, virtual device都要安 ...

  9. LIMIT语句解析及本章简单回顾(二十九)

    一.LIMIT 限制查询结果返回的数量 [LIMIT {[offset,] row_count | row_count OFFSET offset}] select * from user; 除了可以 ...

  10. RelativeLayout中的baseline

    比如,加入两个相邻的TextView,给第二个TextView一个大一点的padding(比如20dp),如果加了layout_alignBaseline到第二个TextView中的话, TextVi ...