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长度 + 以它 ...
随机推荐
- android文件管理器源码、斗鱼直播源码、企业级erp源码等
Android精选源码 文件清理管理器 自定义水平带数字的进度条以及自定义圆形带数字的进度条 利用sectionedRecyclerViewAdapter实现分组列表的recyclerView源码 流 ...
- ubantu下su命令Authentication failure失败的解决方式
Ubuntu安装后,root用户默认是被锁定了的,不允许登录,也不允许 su 到 root . 可以使用: sudo passwd 来重新设置root密码,后即可登陆root. ortonwu@ubu ...
- 动态链接库(DLL)编写经验
我首先说明DLL的生成方法,之后再补充一些特殊之处. 生成方法: 1.对需要导出的类,在头文件中添加 #ifdef CLASS _API #define CLASS_API _declspec(dll ...
- [国嵌笔记][008-009][远程登录Linux]
[国嵌笔记][008][远程登录Linux] 1.windows与Linux能够相互ping通 2.关闭Linux防火墙 /etc/init.d/iptables stop 3.通过ssh(字符界面) ...
- [国嵌笔记][005][Linux命令详解]
用户管理类命令 添加用户:useradd name 删除用户:userdel -r name "-r"表示删除对应用户的目录 修改密码:passwd name 切换用户:su - ...
- .26-浅析webpack源码之事件流make(1)
compilation事件流中,依然只是针对细节步骤做事件流注入,代码流程如图: // apply => this-compilation // apply => compilation ...
- 解析MYsql explain执行计划extra列输出
EXPLAIN Extra 列信息: explain Extra列输出包含了关于mysql如何解决query的额外信息,特别是出现Using filesort 和 using temporary时,应 ...
- mybatis_SQL缓存(5)
<settings> <!-- 这个配置使全局的映射器启用或禁用缓存 --> <setting name="cacheEnabled" value=& ...
- mysql myisam转innodb的2种方法
mysql myisam转innodb的2种方法 mysql中的myisam和innodb有什么区别.一个好比便利店,一个好比大型购物中心,他们是为了适应不同的场合而存在的.当流量比较小,我们可以 ...
- 【good】在CentOS 6.x上安装GlusterFS
转发:http://quenywell.com/install-glusterfs-on-centos-6-x/ 本文主要介绍如何在CentOS 6.x上快速安装GlusterFS.GlusterFS ...