题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1376

题解:显然这题暴力的方法很容易想到就是以每个数为结尾最长的有多少个,但是这样显然会超时所以要想一个方法去优化,要么用stl要么就是数据结构

线段树是个可以考虑的对象因为这也是求区间的和于是稍微将原数组优化一下,按照大小排序一下然后再按照下标更新这样能确保有序。具体看一下代码

还有一点要提一下有时候要考虑两维的东西可以适当排一下序使其变成一维有序这样就方便很多了。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define mod 1000000007
using namespace std;
const int M = 5e4 + 10;
typedef long long ll;
struct node {
int id , val;
}a[M];
struct TnT {
int l , r;
ll num;
int Max;
}T[M << 2];
void push_up(int i) {
T[i].Max = max(T[i << 1].Max , T[(i << 1) | 1].Max);
if(T[i << 1].Max == T[(i << 1) | 1].Max) {
T[i].num = T[i << 1].num % mod + T[(i << 1) | 1].num % mod;
}
else {
if(T[i << 1].Max > T[(i << 1) | 1].Max) T[i].num = T[i << 1].num % mod;
else T[i].num = T[(i << 1) | 1].num % mod;
}
T[i].num %= mod;
}
void build(int l , int r , int i) {
int mid = (l + r) >> 1;
T[i].l = l , T[i].r = r , T[i].num = 0 , T[i].Max = 0;
if(l == r) return ;
build(l , mid , i << 1);
build(mid + 1 , r , (i << 1) | 1);
push_up(i);
}
void update(int pos , int i , int Max , ll num) {
int mid = (T[i].l + T[i].r) >> 1;
if(T[i].l == T[i].r && T[i].l == pos) {
T[i].Max = Max ,T[i].num = num % mod;
return ;
}
if(mid < pos) update(pos , (i << 1) | 1 , Max , num);
else update(pos , i << 1 , Max , num);
push_up(i);
}
TnT query(int l , int r , int i) {
int mid = (T[i].l + T[i].r) >> 1;
if(T[i].l == l && T[i].r == r) {
return T[i];
}
push_up(i);
TnT resl , resr , res;
if(mid < l) return query(l , r , (i << 1) | 1);
else if(mid >= r) return query(l , r , i << 1);
else {
resl = query(l , mid , i << 1);
resr = query(mid + 1 , r , (i << 1) | 1);
if(resl.Max == resr.Max) {
res.Max = resl.Max , res.num = resl.num % mod + resr.num % mod;
}
else {
if(resl.Max > resr.Max) res.Max = resl.Max , res.num = resl.num % mod;
else res.Max = resr.Max , res.num = resr.num % mod;
}
res.num %= mod;
return res;
}
}
bool cmp(node x , node y) {
if(x.val == y.val) return x.id > y.id;
return x.val < y.val;
}
int main() {
int n;
scanf("%d" , &n);
for(int i = 1 ; i <= n ; i++) scanf("%d" , &a[i].val) , a[i].id = i;
sort(a + 1 , a + 1 + n , cmp);
build(1 , n , 1);
for(int i = 1 ; i <= n ; i++) {
TnT gg = query(1 , a[i].id , 1);
update(a[i].id , 1 , gg.Max + 1 , max((ll)1 ,gg.num % mod));
}
printf("%lld\n" , (T[1].num + mod) % mod);
return 0;
}

51nod 1376 最长递增子序列的数量(不是dp哦,线段树 +  思维)的更多相关文章

  1. 51nod 1376 最长递增子序列的数量(线段树)

    51nod 1376 最长递增子序列的数量 数组A包含N个整数(可能包含相同的值).设S为A的子序列且S中的元素是递增的,则S为A的递增子序列.如果S的长度是所有递增子序列中最长的,则称S为A的最长递 ...

  2. 51Nod 1376 最长递增子序列的数量 —— LIS、线段树

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1376 1376 最长递增子序列的数量 基准时间限制:1 秒 空 ...

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

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

  4. 51Nod 1376 最长递增子序列的数量 (DP+BIT)

    题意:略. 析:dp[i] 表示以第 i 个数结尾的LIS的长度和数量,状态方程很好转移,先说长度 dp[i] = max { dp[j] + 1 | a[i] > a[j] && ...

  5. 51nod 1376 最长上升子序列的数量 | DP | vector怒刷存在感!

    51nod 1376 最长上升子序列的数量 题解 我们设lis[i]为以位置i结尾的最长上升子序列长度,dp[i]为以位置i结尾的最长上升子序列数量. 显然,dp[i]要从前面的一些位置(设为位置j) ...

  6. 【51nod】1376 最长递增子序列的数量

    数组A包含N个整数(可能包含相同的值).设S为A的子序列且S中的元素是递增的,则S为A的递增子序列.如果S的长度是所有递增子序列中最长的,则称S为A的最长递增子序列(LIS).A的LIS可能有很多个. ...

  7. 51nod1376 最长递增子序列的数量

    O(n2)显然超时.网上找的题解都是用奇怪的姿势写看不懂TAT.然后自己YY.要求a[i]之前最大的是多少且最大的有多少个.那么线段树维护两个值,一个是当前区间的最大值一个是当前区间最大值的数量那么我 ...

  8. 51nod 1134 最长递增子序列

    题目链接:51nod 1134 最长递增子序列 #include<cstdio> #include<cstring> #include<algorithm> usi ...

  9. 51nod 1218 最长递增子序列 | 思维题

    51nod 1218 最长递增子序列 题面 给出一个序列,求哪些元素可能在某条最长上升子序列中,哪些元素一定在所有最长上升子序列中. 题解 YJY大嫂教导我们,如果以一个元素结尾的LIS长度 + 以它 ...

随机推荐

  1. Python之assert断言语句

    关键字assert构成断言语句,主要是可以在我们书写一个新的程序时,可以使用它帮我们锁定bug范围. 表达式: assert 表达式 ‘窗口提示的信息’ 括号中的项目为选填项目,选填项目将会在表达式的 ...

  2. 深入理解JVM-类加载器深入解析(3)

    深入理解JVM-类加载器深入解析(3) 获得ClassLoader的途径 获得当前类的ClassLoader clazz.getClassLoader() 获得当前线程上下文的ClassLoader ...

  3. springMVC(一) --前端控制器(DispatcherServlet)的作用

        SpringMVC是Spring中的模块,它实现了mvc设计模式的web框架,首先用户发出请求,请求到达SpringMVC的前端控制器(DispatcherServlet),前端控制器根据用户 ...

  4. apicloud 开发环境搭建

     之前做过appcan 手机应用的开发,工作需要切换的apicloud , 开发环境的的搭建是开发的第一步,let's go 1新建应用 step1  注册账号 注册apicloud 账号:https ...

  5. 正确使用sqlcipher for Android

    android-database-sqlcipher是基于SQLCipher的数据库加密框架,支持android4到android9,经常用来对android的SqlLite进行加密,现在支持Grad ...

  6. Codeforces 436D Pudding Monsters

    题意简述 开始有无限长的一段格子,有n个格子种有布丁怪兽,一开始连续的布丁怪兽算一个布丁怪兽. 每回合你可以将一个布丁怪兽向左或右移动,他会在碰到第一个布丁怪兽时停下,并与其合并. 有m个特殊格子,询 ...

  7. 洛谷 P4401 [IOI2007]Miners 矿工配餐

    题意简述 有两个矿洞,已知食物的种类(≤3)和顺序,将他们送往任一矿洞, 若一个矿洞3次食物相同,贡献1:若有2种不同食物,贡献2:若有3种不同食物,贡献3 求最大贡献 题解思路 food[i] 为当 ...

  8. 《机器学习技法》---GBDT

    1 对决策树使用adaboost 对决策树使用adaboost时,有以下几个问题: (1)adaboost每次更新的样本权重如何应用到决策树中? 由于我们不知道决策树的err目标是什么,因此通常的方法 ...

  9. 三步理解--门控循环单元(GRU),TensorFlow实现

    1. 什么是GRU 在循环神经⽹络中的梯度计算⽅法中,我们发现,当时间步数较⼤或者时间步较小时,循环神经⽹络的梯度较容易出现衰减或爆炸.虽然裁剪梯度可以应对梯度爆炸,但⽆法解决梯度衰减的问题.通常由于 ...

  10. (三)c#Winform自定义控件-有图标的按钮

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...