Tjoi2016&Heoi2016序列

Description

佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他。玩具上有一个数列,数列中某些项的值

可能会变化,但同一个时刻最多只有一个值发生变化。现在佳媛姐姐已经研究出了所有变化的可能性,她想请教你
,能否选出一个子序列,使得在任意一种变化中,这个子序列都是不降的?请你告诉她这个子序列的最长长度即可
。注意:每种变化最多只有一个值发生变化。在样例输入1中,所有的变化是:
1 2 3
2 2 3
1 3 3
1 1 31 2 4
选择子序列为原序列,即在任意一种变化中均为不降子序列在样例输入2中,所有的变化是:3 3 33 2 3选择子序列
为第一个元素和第三个元素,或者第二个元素和第三个元素,均可满足要求

Input

输入的第一行有两个正整数n, m,分别表示序列的长度和变化的个数。接下来一行有n个数,表示这个数列原始的

状态。接下来m行,每行有2个数x, y,表示数列的第x项可以变化成y这个值。1 <= x <= n。所有数字均为正整数
,且小于等于100,000

Output

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

Sample Input

3 4
1 2 3
1 2
2 3
2 1
3 4

Sample Output

3
 
  正解:CDQ分治。
  想了好久没想到怎么做这个数数题,结果告诉我是CDQ(qiû)分治... ...果然我弱啊。
  然后知道是CDQ之后就抠了好久偏序。
  发现对于两个满足变化的玩具i和j,设一个玩具的最小变化值为L,最大为R,原始为A。
  因为总是只有一个玩具的状态改变,所以可以列出:
    i<j;
    R[i]<=A[j];
    A[i]<=L[j];
  这样就列出了一个三维偏序。使用CDQ分治可以解决问题。
  但是我在这里要做一个反思。我为了省力在外面那一层的偏序是rank,也就是i<j,因为可以不用sort。
  但是这样下面的小于等于+重复元A就很不好做... ...也可能是我的CDQ学的不到家。
  经过QT的点拔(代码强×)后我发现在外面搞的偏序是A的话就比较好搞。
  在外面把A升序了,在CDQ里面先按rank分成左右,同时又不破坏两边A的升序。这个很好搞。
  然后CDQ(l,mid),回来的时候把左边按R升序。
  那么现在就是关键!这个时候——
    左边的rank均小于右边的rank。
    左边的R是升序的,右边的A是升序的。
  然后就是一个红红火火恍恍惚惚的树状数组操作了。
  然后CDQ(mid+1,r),再把右边按R升个序。
  然后QT告诉窝删除树状数组的时候绝对不能用memset... ...是绝对不能... ...

  直接把l到mid的重新搞一边清零。
  看来窝以前的CDQ都是数据水才过去的啊,原来有这么多注意点。
  所以说要把重复元做第一关键字吗,所以我真是菜啊。
  但是为什么菜鸡的CDQ上了第一版呢... ...还是得%QT。
#include    <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
#include <complex>
#include <stack>
#define LL long long int
#define dob double
using namespace std; const int N = 100010;
struct Data{int rk,l,a,r,len;}s[N],f[N];
int n,m,T[N],Ans; int gi()
{
int x=0,res=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')res*=-1;ch=getchar();}
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*res;
} inline bool cmpa(const Data &a,const Data &b){return a.a<b.a;} inline int lb(int k){return k&-k;} inline void update(int x,int mx){for(;x<=n;x+=lb(x))T[x]=max(T[x],mx);} inline int query(int x){int ans=0;for(;x;x-=lb(x))ans=max(ans,T[x]);return ans;} inline void clean(int x){for(;x<=n;x+=lb(x))T[x]=0;} inline void merge(int l,int r)
{
if(l==r)return;
int mid=(l+r)>>1;
int x=l,y=mid+1,i=l;
Data f[N];
while(x<=mid && y<=r){
if(s[x].r<=s[y].r)
f[i++]=s[x++];
else f[i++]=s[y++];
}
while(x<=mid)f[i++]=s[x++];
while(y<=r)f[i++]=s[y++];
for(i=l;i<=r;++i)s[i]=f[i];
} inline void CDQ(int l,int r)
{
if(l==r){s[l].len=max(s[l].len,1);return;}
int mid=(l+r)>>1;
int x=l,y=mid+1;
for(int i=l;i<=r;++i)
if(s[i].rk<=mid)f[x++]=s[i];
else f[y++]=s[i];
for(int i=l;i<=r;++i)s[i]=f[i];
CDQ(l,mid);merge(l,mid);
x=l;y=mid+1;
while(x<=mid && y<=r){
if(s[x].r<=s[y].a)
update(s[x].a,s[x].len),++x;
else s[y].len=max(s[y].len,query(s[y].l)+1),++y;
}
while(y<=r)s[y].len=max(s[y].len,query(s[y].l)+1),++y;
for(int i=l;i<=mid;++i)clean(s[i].a);
CDQ(mid+1,r);merge(mid+1,r);
} int main()
{
n=gi();m=gi();
for(int i=1;i<=n;++i)
s[i].rk=i,s[i].l=s[i].r=s[i].a=gi(),s[i].len=0;
for(int i=1;i<=m;++i){
int x=gi(),y=gi();
s[x].l=min(s[x].l,y);
s[x].r=max(s[x].r,y);
}
sort(s+1,s+n+1,cmpa);
CDQ(1,n);
for(int i=1;i<=n;++i)Ans=max(Ans,s[i].len);
printf("%d\n",Ans);
return 0;
}

  

 

BZOJ 4553 Tjoi2016&Heoi2016 序列的更多相关文章

  1. BZOJ 4553 [Tjoi2016&Heoi2016]序列 ——CDQ分治 树状数组

    考虑答案的构成,发现是一个有限制条件的偏序问题. 然后三个维度的DP,可以排序.CDQ.树状数组各解决一维. #include <map> #include <cmath> # ...

  2. 4553: [Tjoi2016&Heoi2016]序列

    4553: [Tjoi2016&Heoi2016]序列 链接 分析: 注意所有m此操作中,只会发生一个,于是考虑dp.dp[i]=dp[j]+1,j<i,a[j]<=L[i],R[ ...

  3. [BZOJ4553][TJOI2016&&HEOI2016]序列(CDQ分治)

    4553: [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 554[Su ...

  4. [BZOJ4553][Tjoi2016&Heoi2016]序列 cdp分治+dp

    4553: [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 260  Solved: 133[Sub ...

  5. 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组

    [BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...

  6. bzoj4553 [Tjoi2016&Heoi2016]序列 树状数组(区间最大值)+cqd

    [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1006  Solved: 464[Submit][ ...

  7. BZOJ 4552: [Tjoi2016&Heoi2016]排序

    4552: [Tjoi2016&Heoi2016]排序 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 579  Solved: 322[Sub ...

  8. BZOJ 4551: [Tjoi2016&Heoi2016]树

    4551: [Tjoi2016&Heoi2016]树 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 748  Solved: 394[Subm ...

  9. Bzoj 4556: [Tjoi2016&Heoi2016]字符串

    4556: [Tjoi2016&Heoi2016]字符串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 177  Solved: 92[Sub ...

随机推荐

  1. DNS单机部署以及智能dns部署

    dns理论 dns的出现 网络出现的早期是使用IP地址通讯的,那时就几台主机通讯.但是随着接入网络主机的增多,这种数字标识的地址非常不便于记忆,UNIX上就出现了建立一个叫做hosts的文件(Linu ...

  2. Thinkphp导入外部类的方法

    相信很多人在使用TP时候都苦恼使用外部类各种不成功 下面为大家详细介绍下引用方法和注意细节 手动加载第三方类库 由于第三发类库没有具体的命名空间,所以需要使用以下几种方法手动导入 1.import方法 ...

  3. 模板文件引入css样式文件

    引用路径问题:相对路径和绝对路径 相对路径:相对路口文件index.php设置 绝对路径:从虚拟主机站点目录开始设置 css样式文件引入图片,路径的设置 相对地址:相对css文件本身设置 ①模板文件 ...

  4. Numpy入门 - 生成数组

    今天是Numpy入门系列教程第一讲,首先是安装Numpy: $ pip install numpy numpy是高性能科学计算和数据分析的基础包,本节主要介绍生成连续二维数组.随机二维数组和自定义二维 ...

  5. 迭代子模式(Iterator)

    迭代子模式(Iterator) 顾名思义,迭代器模式就是顺序访问聚集中的对象,一般来说,集合中非常常见,如果对集合类比较熟悉的话,理解本模式会十分轻松.这句话包含两层意思:一是需要遍历的对象,即聚集对 ...

  6. 【java系列】java开发环境搭建

    描述 本篇文章主要讲解基于windows 10系统搭建java开发环境,主要内容包括如下: (1)安装资料准备 (2)安装过程讲解 (3)测试是否安装成功 (4)Hello Word测试 1   安装 ...

  7. NYOJ 119 士兵杀敌(三) RMQ ST

    NYOJ 119 士兵杀敌(三) RMQ ST 题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=119 思路: ST在线 预处理O(nlog ...

  8. 蓝桥杯 剪邮票 全排列+DFS

    剪邮票 如[图1.jpg], 有12张连在一起的12生肖的邮票. 现在你要从中剪下5张来,要求必须是连着的. (仅仅连接一个角不算相连) 比如,[图2.jpg],[图3.jpg]中,粉红色所示部分就是 ...

  9. yii2.0中添加二维数组,多条数据。

    /** * @inheritdoc 批量添加 * @params $add array 添加数据 */public function add_all($add){ $connection = \Yii ...

  10. 如何用九条命令在一分钟内检查Linux服务器性能?

    一.uptime命令 这个命令可以快速查看机器的负载情况.在Linux系统中,这些数据表示等待CPU资源的进程和阻塞在不可中断IO进程(进程状态为D)的数量.这些数据可以让我们对系统资源使用有一个宏观 ...