51nod 1376 最长递增子序列的数量(线段树)
51nod 1376 最长递增子序列的数量
第1行:1个数N,表示数组的长度。(1 <= N <= 50000)
第2 - N + 1行:每行1个数A[i],表示数组的元素(0 <= A[i] <= 10^9)
输出最长递增子序列的数量Mod 1000000007。
5
1
3
2
0
4
2
/*
51nod 1376 最长递增子序列的数量 problem:
给你一个数组,求其中最长递增子序列有多少个 solve:
对于第i个数a[i]而言,它需要知道已经出现的[1,a[i]-1]中最长递增子序列的长度以及数量. 所以可以利用线段树来维护,
然后利用长度和数量来更新a[i] hhh-2016/09/03-16:41:1
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <math.h>
#include <queue>
#include <set>
#include <map>
#define lson i<<1
#define rson i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define scanfi(a) scanf("%d",&a)
#define scanfs(a) scanf("%s",a)
#define scanfl(a) scanf("%I64d",&a)
#define scanfd(a) scanf("%lf",&a)
#define key_val ch[ch[root][1]][0]
#define eps 1e-7
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const ll mod = 1000000007;
const int maxn = 50010;
const double PI = acos(-1.0);
int a[maxn],t[maxn];
struct node
{
int l,r;
ll Max,num;
int mid;
} tree[maxn << 2]; void push_up(int i)
{
if(tree[lson].Max == tree[rson].Max)
{
tree[i].Max = tree[lson].Max;
tree[i].num = tree[lson].num + tree[rson].num;
tree[i].num %= mod;
}
else if(tree[lson].Max > tree[rson].Max)
{
tree[i].Max = tree[lson].Max;
tree[i].num = tree[lson].num;
}
else
{
tree[i].Max = tree[rson].Max;
tree[i].num = tree[rson].num;
}
} void build(int i,int l,int r)
{
tree[i].l = l,tree[i].r = r;
tree[i].Max = tree[i].num = 0;
tree[i].mid = (l+r) >> 1;
if(l == r)
return ;
build(lson,l,tree[i].mid);
build(rson,tree[i].mid + 1,r);
push_up(i);
} void push_down(int i)
{ } void update(int i,int k,ll len,ll many)
{
if(tree[i].l == tree[i].r && tree[i].l == k)
{
if(tree[i].Max < len) tree[i].Max = len,tree[i].num = many;
else if(tree[i].Max == len) tree[i].num += many;
tree[i].num %= mod;
return ;
}
int mid = tree[i].mid;
if(k <= mid)
update(lson,k,len,many);
else update(rson,k,len,many);
push_up(i);
}
ll tans,tnum;
void query(int i,int l,int r)
{
if(l > r)
{
tans = 0,tnum = 1;
return ;
}
if(tree[i].l >= l && tree[i].r <= r)
{
if(tans == -1)
tans = tree[i].Max,tnum = tree[i].num;
else
{
if(tans == tree[i].Max) tnum += tree[i].num;
else if(tans < tree[i].Max)
{
tans = tree[i].Max,tnum = tree[i].num;
}
tnum %= mod;
}
return ;
}
push_down(i);
int mid = tree[i].mid;
if(l <= mid)
query(lson,l,r);
if(r > mid)
query(rson,l,r);
return;
} int cnt = 0;
int main()
{
int n;
while(scanfi(n) != EOF)
{
for(int i = 0; i< n;i++){
scanfi(a[i]);
t[i] = a[i];
}
sort(a,a+n);
cnt = 0;
for(int i = 1;i < n;i++)
{
if(a[i] != a[cnt])
a[++cnt] = a[i];
}
// for(int i = 0;i <= cnt;i++)
// printf("%d\n",a[i]);
build(1,0,cnt);
ll tMax = 0,ans = 0;
int id = lower_bound(a,a+cnt+1,t[0]) -a;
update(1,id,1,1);
tMax = 1,ans = 1;
for(int i = 1;i < n;i++)
{
id = lower_bound(a,a+cnt+1,t[i]) -a;
// cout << id <<" " ;
tans = -1,tnum = 0;
query(1,0,id-1);
if(!tans && !tnum)
tnum = 1;
if(tMax < tans+ 1) tMax = tans+1,ans = tnum;
else if(tMax == tans+1) ans += tnum;
ans %= mod;
update(1,id,tans + 1,tnum);
}
// cout <<endl;
printf("%I64d\n",ans);
}
return 0;
}
51nod 1376 最长递增子序列的数量(线段树)的更多相关文章
- 51Nod 1376 最长递增子序列的数量 —— LIS、线段树
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1376 1376 最长递增子序列的数量 基准时间限制:1 秒 空 ...
- 51NOD 1376 最长递增子序列的数量 [CDQ分治]
1376 最长递增子序列的数量 首先可以用线段树优化$DP$做,转移时取$0...a[i]$的最大$f$值 但我要练习$CDQ$ $LIS$是二维偏序问题,偏序关系是$i<j,\ a_i< ...
- 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可能有很多个. ...
- 51nod-1134 最长递增子序列,用线段树将N^2的dp降到NlogN
题目链接 给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递增的) 例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10. Input 第1行 ...
- 51nod1376 最长递增子序列的数量
O(n2)显然超时.网上找的题解都是用奇怪的姿势写看不懂TAT.然后自己YY.要求a[i]之前最大的是多少且最大的有多少个.那么线段树维护两个值,一个是当前区间的最大值一个是当前区间最大值的数量那么我 ...
- 51nod 1134 最长递增子序列
题目链接:51nod 1134 最长递增子序列 #include<cstdio> #include<cstring> #include<algorithm> usi ...
随机推荐
- python 归并排序
def merge_sort(alist): if len(alist) <= 1: return alist # 二分分解 num = len(alist)/2 left = merge_so ...
- android 检查软件是否有更新版本
import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import com.yuxin.m ...
- IDEA之Jrebel插件激活
问题: 码农日常中,热部署是必不可少的,而jrebel插件很好的实现热部署功能. IDEA下载jrebel插件,可以免费试用15天,但之后就无法使用.因为Jrebel是收费的. 解决方法: 楼主也是百 ...
- 02-移动端开发教程-CSS3新特性(中)
1. 新的背景 背景在CSS3中也得到很大程度的增强,比如背景图片尺寸.背景裁切区域.背景定位参照点.多重背景等. 1.1 background-size设置背景图片的尺寸 cover会自动调整缩放比 ...
- 《javascript设计模式与开发实践》阅读笔记(10)—— 组合模式
组合模式:一些子对象组成一个父对象,子对象本身也可能是由一些孙对象组成. 有点类似树形结构的意思,这里举一个包含命令模式的例子 var list=function(){ //创建接口对象的函数 ret ...
- python 关键字的操作
声明:本文章默认使用的是python 3.6.1 1.要想当个牛逼的程序员,就要精通各种hello world的写法,当然,我不牛逼,只能用python去写^..^! print("Hell ...
- Highcharts tooltip显示多条线的信息
直接上代码吧,简单粗暴点: tooltip: { shared: true, valueSuffix: '分', formatter: function () { let s = "&quo ...
- IntelliJ IDEA sass环境配置及常见报错处理
1.下载安装ruby,网上教程很多的,安装完之后在命令行输入ruby -v检查一下是否安装成功了.(注意安装的时候要勾选第二项).
- api-gateway实践(01)服务网关 - 原型功能
一.服务注册 1.增加组:LsqGrpA 2.增加版本:LsqVerA 3.增加api:LsqApiA 3.1.基本信息 3.2.前端定义 3.3.后端定义 二.服务上线和服务授权 1.服务上线 2. ...
- "共振式”项目管理
"共振式”项目管理--是我第一个提出的吗?:) 脑子里突然想到项目管理的一些事情,然后想到项目其实是有节奏的,项目中的人员其实如果找到了这个节奏,踏准了节奏,一切将是顺风顺水. 刚准备动笔时 ...