题目链接:洛谷

推荐阅读:2019年集训队论文《浅谈杨氏矩阵在信息学竞赛中的应用》

首先我们来看一个东西,叫做Young表。

它是长一个阶梯状的东西(行长和列长都是递减的),并且每一行和每一列都是按照一个不等号单调的。比如这是一个单调上升的Young表。

1 2 3 4
2 5 7
3 6

那么有一个序列转化为Young表的(按行)插入算法\(S\leftarrow x\)(以单调不升为例):

在当前行找第一个\(\le x\)且最小的数\(p\),若这个位置是空,那么直接将\(x\)放到行末,否则将\(x,p\)交换,然后插入下一行。一个个插入就能得到一个 Young 表。

不知道为什么,这个序列的前\(k\)行就是在这个序列里面取\(k\)个单调不上升子序列的使得总长最大。根据 Dilworth 定理,前\(k\)行的子序列就是最长上升子序列为\(k\)的最长子序列。所以询问的就是 Young 表的前\(k\)行的元素个数。

我们发现 Young 表插入算法的时间复杂度是\(O(r\log c)\)的,一看就很不平衡的样子。然后有一个结论就是,如果改为单调上升的 Young 表,那么这两个 Young 表互为转置(或者说按列插入和按行插入得到的结果是一样的)。我们知道这个 Young 表的每个元素的横坐标和纵坐标不可能同时\(>\sqrt{n}\),所以维护这两个 Young 表的前\(\sqrt n\)行,用树状数组维护每行元素个数的前缀和。

时间复杂度为\(O(n\sqrt{n}\log n+q\log n)\)。

#include<bits/stdc++.h>
#define Rint register int
using namespace std;
const int N = 200005, M = 255, inf = 0x3f3f3f3f;
int n, q, siz, b[N], ans[N], tr[N];
inline int lowbit(int x){return x & -x;}
inline void change(int pos, int val){while(pos < N){tr[pos] += val; pos += lowbit(pos);}}
inline int query(int pos){int ans = 0; while(pos){ans += tr[pos]; pos -= lowbit(pos);} return ans;}
struct Table {
vector<int> vec[M];
int sign;
inline void insert(int x, int len, int p){
if(x > siz) return;
int l = 0, r = min(len, (int) vec[x].size()), mid;
while(l < r){
mid = l + r >> 1;
if(sign ^ (vec[x][mid] < p)) r = mid;
else l = mid + 1;
}
if(r == vec[x].size()){
vec[x].push_back(p);
if(sign){if(r >= siz) change(r + 1, 1);}
else change(x, 1);
} else {
swap(vec[x][r], p);
insert(x + 1, r, p);
}
}
} T1, T2;
struct Query {
int m, k, id;
inline bool operator < (const Query &o) const {return m < o.m || (m == o.m && k < o.k);}
} que[N];
int main(){
T1.sign = 0, T2.sign = 1;
scanf("%d%d", &n, &q); siz = sqrt(n);
for(Rint i = 1;i <= n;i ++) scanf("%d", b + i);
for(Rint i = 1;i <= q;i ++) scanf("%d%d", &que[i].m, &que[i].k), que[i].id = i;
sort(que + 1, que + q + 1);
for(Rint i = 1, j = 1;i <= n;i ++){
T1.insert(1, inf, b[i]); T2.insert(1, inf, b[i]);
while(j <= q && que[j].m == i) ans[que[j].id] = query(que[j].k), ++ j;
}
for(Rint i = 1;i <= q;i ++) printf("%d\n", ans[i]);
}

Luogu3774 [CTSC2017]最长上升子序列 【Young表,根号分治】的更多相关文章

  1. 51NOD 1376 最长递增子序列的数量 [CDQ分治]

    1376 最长递增子序列的数量 首先可以用线段树优化$DP$做,转移时取$0...a[i]$的最大$f$值 但我要练习$CDQ$ $LIS$是二维偏序问题,偏序关系是$i<j,\ a_i< ...

  2. bzoj4904 [Ctsc2017]最长上升子序列

    我们发现他让求的东西很奇怪,于是通过某D开头定理,我们转化为前m位的序列用k个不上升子序列最多能覆盖多少.数据范围小的时候可以网络流做,但是这道题显然不支持网络流的复杂度.然后有一个奇怪的东西叫杨氏矩 ...

  3. 【bzoj5161】最长上升子序列 状压dp+打表

    题目描述 现在有一个长度为n的随机排列,求它的最长上升子序列长度的期望. 为了避免精度误差,你只需要输出答案模998244353的余数. 输入 输入只包含一个正整数n.N<=28 输出 输出只包 ...

  4. 经典递归问题:0,1背包问题 kmp 用遗传算法来解背包问题,hash表,位图法搜索,最长公共子序列

    0,1背包问题:我写笔记风格就是想到哪里写哪里,有很多是旧的也没删除,代码内部可能有很多重复的东西,但是保证能运行出最后效果 '''学点高大上的遗传算法''' '''首先是Np问题的定义: npc:多 ...

  5. 用python实现最长公共子序列算法(找到所有最长公共子串)

    软件安全的一个小实验,正好复习一下LCS的写法. 实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向. 相对 ...

  6. 动态规划之最长公共子序列(LCS)

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

  7. 准备NOIP2017 最长公共子序列(模版)

    一些概念: (1)子序列: 一个序列A = a1,a2,--an,中任意删除若干项,剩余的序列叫做A的一个子序列.也可以认为是从序列A按原顺序保留任意若干项得到的序列.例如:   对序列 1,3,5, ...

  8. [ACM] hdu 1025 Constructing Roads In JGShining's Kingdom (最长递增子序列,lower_bound使用)

    Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65 ...

  9. 算法导论-动态规划(最长公共子序列问题LCS)-C++实现

    首先定义一个给定序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果,其形式化定义如下:给定一个序列X = <x1,x2 ,..., xm>,另一个序列Z =<z1,z2  ...

随机推荐

  1. RequestBody只能读取一次的问题

    一.为什么只能读一次 原因很简单:因为是流.想想看,java中的流也是只能读一次,因为读完之后,position就到末尾了. 二.解决办法 思路:第一次读的时候,把流数据暂存起来.后面需要的时候,直接 ...

  2. Python之TensorFlow的基本介绍-1

    一.TensorFlow™是一个基于数据流编程(dataflow programming)的符号数学系统,被广泛应用于各类机器学习(machine learning)算法的编程实现,其前身是谷歌的神经 ...

  3. windows下安装hexo和生成博客

    首先在电脑上安装node和git,这个只要在相关官网的下载然后一步安装即可. 然后在你的电脑上新建一个文件夹,用来存放你的博客文件,比如创建hexo 进入该文件,右键打开git bash 安装hexo ...

  4. HTML5新增元素和移除的元素?

    新增元素: 图像Canvas 多媒体video.audio 本地存储localStorage.sessionStorage 语义化更好的内容元素aticle.header.footer.nav.sec ...

  5. JAVA基础之ServletContext应用

    创建一个登陆的界面,并且统计次数! 导入jar包; 1. driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/java0603?u ...

  6. requests模块 简单使用

    目录 requests模块 简单使用 Anaconda简单了解 简单了解 requests模块 使用requests模块 爬取搜狗首页源码数据 实现一个简易的网页采集器 解决乱码问题 解决UA检测问题 ...

  7. springboot整合tkmybatis

    tkmybatis是什么? tkmybatis是为了简化mybatis单表的增删改查而诞生的,极其方便的使用MyBatis单表的增删改查,在使用mybatis单表增删改查时,可以直接调用tkmybat ...

  8. paroot忘记root密码

    打开虚拟机在倒计时进入系统前按下e键然后按照下图修改即可 crtl+x重启 mount –rw –o remount /保证磁盘可读写 然后执行passwd

  9. ABAP开发者上云的时候到了 - 现在大家可以免费使用SAP云平台ABAP环境的试用版了

    之前Jerry已经写了一系列SAP Cloud Platform ABAP编程环境的文章,当时使用的环境,是SAP专门为SAP社区导师们创建的. 当时也有朋友留言,询问大家何时才能使用到免费的SAP云 ...

  10. WPF如何设置启动窗口

    在做系统时,我们想在启动时显示自己想显示的界面,和Winform不同的是它有两种方法 1.在App.xaml中 <Application x:Class="WpfApp1.App&qu ...