51NOD 1376 最长递增子序列的数量 [CDQ分治]
首先可以用线段树优化$DP$做,转移时取$0...a[i]$的最大$f$值
但我要练习$CDQ$
$LIS$是二维偏序问题,偏序关系是$i<j,\ a_i<a_j$
$CDQ$分治可以解决偏序问题
$CDQ(l,r)\ :$
$CDQ(l,mid)$
$[l,r]$按$a$排序,$[l,mid] \rightarrow\ [mid+1,r]$
$CDQ(mid+1,r)$
这个排序没法用归并排序,因为你要用最优的$f[k],k\in [mid+1,r]$来更新$k$的右面,必须先$[l,mid] \rightarrow\ [mid+1,r]$获得最优的$f[k]$才行,而那些计数类问题就不需要了
我尝试了很多写法,最后分治里还是采用了间接排序,这样不影响$i<j$这个关系
[2017-02-25]不排序用一个维护区间最大值的数据结构也可以,更新的时候取$0...a[i]$的最大$f$值(这样你还分治什么啊?!)
注意严格递增
于是$LIS$现在可以用$CDQ$水过啦!!!
其实二维的最长上升子序列用$CDQ$分治是没有意义的,无论如何都比数据结构维护多一个$log$
该死一下午就写这玩意了
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=5e4+,MOD=1e9+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,a[N],ref[N];
inline bool cmp(int x,int y){return a[x]==a[y]?x>y:a[x]<a[y];}//strict
inline void mod(int &x){if(x>=MOD) x-=MOD;}
int f[N],g[N];
void CDQ(int l,int r){
if(l==r) return;
int mid=(l+r)>>;
CDQ(l,mid);
for(int i=l;i<=r;i++) ref[i]=i;
sort(ref+l,ref+r+,cmp);
int mx=,cnt=;
for(int i=l;i<=r;i++){
int id=ref[i];
if(id<=mid){
if(f[id]>mx) mx=f[id],cnt=g[id];
else if(f[id]==mx) mod(cnt+=g[id]);
}else{
if(mx+>f[id]) f[id]=mx+,g[id]=cnt;
else if(f[id]==mx+) mod(g[id]+=cnt);
}
}
CDQ(mid+,r);
}
int main(){
freopen("in","r",stdin);
n=read();
for(int i=;i<=n;i++) a[i]=read(),f[i]=g[i]=;
CDQ(,n);
int mx=,cnt=;
for(int i=;i<=n;i++){
if(f[i]>mx) mx=f[i],cnt=g[i];
else if(f[i]==mx) mod(cnt+=g[i]);
}
printf("%d",cnt%MOD);
}
51NOD 1376 最长递增子序列的数量 [CDQ分治]的更多相关文章
- 51nod 1376 最长递增子序列的数量(线段树)
51nod 1376 最长递增子序列的数量 数组A包含N个整数(可能包含相同的值).设S为A的子序列且S中的元素是递增的,则S为A的递增子序列.如果S的长度是所有递增子序列中最长的,则称S为A的最长递 ...
- 51Nod 1376 最长递增子序列的数量 —— LIS、线段树
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1376 1376 最长递增子序列的数量 基准时间限制:1 秒 空 ...
- 51nod 1376 最长递增子序列的数量(不是dp哦,线段树 + 思维)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1376 题解:显然这题暴力的方法很容易想到就是以每个数为结尾最 ...
- 51Nod 1376 最长递增子序列的数量 (DP+BIT)
题意:略. 析:dp[i] 表示以第 i 个数结尾的LIS的长度和数量,状态方程很好转移,先说长度 dp[i] = max { dp[j] + 1 | a[i] > a[j] && ...
- 51nod 1376 最长上升子序列的数量 | DP | vector怒刷存在感!
51nod 1376 最长上升子序列的数量 题解 我们设lis[i]为以位置i结尾的最长上升子序列长度,dp[i]为以位置i结尾的最长上升子序列数量. 显然,dp[i]要从前面的一些位置(设为位置j) ...
- 【51nod】1376 最长递增子序列的数量
数组A包含N个整数(可能包含相同的值).设S为A的子序列且S中的元素是递增的,则S为A的递增子序列.如果S的长度是所有递增子序列中最长的,则称S为A的最长递增子序列(LIS).A的LIS可能有很多个. ...
- 51nod1376 最长递增子序列的数量
O(n2)显然超时.网上找的题解都是用奇怪的姿势写看不懂TAT.然后自己YY.要求a[i]之前最大的是多少且最大的有多少个.那么线段树维护两个值,一个是当前区间的最大值一个是当前区间最大值的数量那么我 ...
- 51nod 1134 最长递增子序列
题目链接:51nod 1134 最长递增子序列 #include<cstdio> #include<cstring> #include<algorithm> usi ...
- 51nod 1218 最长递增子序列 | 思维题
51nod 1218 最长递增子序列 题面 给出一个序列,求哪些元素可能在某条最长上升子序列中,哪些元素一定在所有最长上升子序列中. 题解 YJY大嫂教导我们,如果以一个元素结尾的LIS长度 + 以它 ...
随机推荐
- Legal or Not(拓扑排序判环)
http://acm.hdu.edu.cn/showproblem.php?pid=3342 Legal or Not Time Limit: 2000/1000 MS (Java/Others) ...
- Linux编译安装Mariadb数据库
一.安装cmake cd /usr/local/src tar zxvf cmake-2.8.12.1.tar.gz cd cmake-2.8.12.1 ./configure 注意报错需要安装gcc ...
- JS使用循环按指定倍数分割数组组成新的数组的方法
今天一个新人同事问了我一个问题,就是有一个像下边这种不知道具体长度的数组,想以每4个为一组,重新组合为一个二维数组,很简单的需求只需要用到一个循环再去取余数就可以了,写了一个小demo在这里把代码包括 ...
- [国嵌攻略][182][Sqlite嵌入式数据库移植]
数据库系统构成 在计算机系统中,保存数据的方式一般有两种: 1.普通文件方式 2.数据库方式 相比于普通文件方式,使用数据库来管理大批量数据具有更高的效率与安全性. 数据库系统一般由三个部分构成 1. ...
- [国嵌笔记][006][Linux文本编辑器]
Linux中常见的文本编辑器有Vi和Emacs Vim有3中工作模式:命令行模式.插入模式.底行模式 1.键入i进入插入模式 2.键入[Esc]退回到命令行模式 3.键入:进入底行模式,再键入wq保存 ...
- TypeScript和Node模块解析策略
一般我们在模块化编码时,总会导入其它模块,通常我们使用如下语法: import { A } from './a'; // ES6语法 import { A } from 'a'; var A = re ...
- JavaScript八张思维导图—编程实践
JS基本概念 JS操作符 JS基本语句 JS数组用法 Date用法 JS字符串用法 JS编程风格 JS编程实践 不知不觉做前端已经五年多了,无论是从最初的jQuery还是现在火热的Angular,Vu ...
- 每天一个linux命令(34):du 命令
Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的. 1.命令格式: du [选项][文件] 2.命令功能 ...
- 织梦dedeCMS留言薄
dedeCMS留言薄模塊名爲guestbook, 留言薄模板:/templets/plus/guestbook.htm; 留言回覆模板: 管理員回覆調用/templets/plus/guestbook ...
- Angular 2 前端 http 传输 model 对象及其外键的问题
个人随笔,记录问题及思路草稿,非文章性质. 对于设备编辑场景,需要显示设备类型(外键), 前端有如下 TypeScript model(此 model 和后端实体 model 通常相对应) ...