引自:wonter巨巨的博客

定义 dp[i] := 以数字 i(不是下标 i)为结尾的最长上升长度

然后用线段树维护 dp[i]:

每个节点维护 2 个信息,一个是当前区间的最大上升长度,一个是最大上升长度的方案数,





这里再详细说下这篇题解。。。也是弱弱自己的理解吧。。。

以1-n的值为线段树所代表的区间;

然后依次更新,题目就是要找上升序列,那么我们只要每次查询0~arr[i]-1范围内最长的那个长度和方案拿出来;

然后再去0到n区间里更新,更新的值是arr[i],长度为查询到的x+1,方案还是查询到的方案y;

具体查询:

我们是想知道在一段区间(从0到值arr[i]-1,这里一定要注意是值!是值!)的最长长度;

所以一直查询到那个区间,然后一直下去就好了;

中间如果出现被mid是夹在被查询区间中间的话,就要比较一下左右两段区间的最长长度





具体更新:

一直要先更新到最底;

然后再往上更新,

往上更新只要比较一下左右子区间的长度就好了;

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+10;
const int mod=1e9+7; struct asd{
int left,right,mid;
int val;
int cnt;
};
asd q[N*4]; void build(int i,int left,int right)
{
q[i].left=left;
q[i].right=right;
q[i].mid=(left+right)>>1;
q[i].cnt=q[i].val=0;
if(left==right)
return;
build(i*2,left,q[i].mid);
build(i*2+1,q[i].mid+1,right);
} void query(int i, int left, int right, int &x, int &y )
{
if(q[i].left==left&&q[i].right==right)
{
x=q[i].val;
y=q[i].cnt;
return;
}
if(right<=q[i].mid)
{
query(i*2, left, right, x, y);
return;
}
if(left>q[i].mid)
{
query(i*2+1,left,right, x, y);
return;
}
int lx,ly;
int rx,ry;
query(i*2,left,q[i].mid,lx,ly);
query(i*2+1,q[i].mid+1,right, rx,ry);
if(lx==rx)
{
x=lx;
y=(ly+ry)%mod;
}
else if(lx>rx)
{
x=lx;
y=ly;
}
else
{
x=rx;
y=ry;
}
} void update(int i,int p,int x,int y)
{
if(q[i].left==q[i].right&&q[i].left==p)
{
if(x>q[i].val)
{
q[i].val=x;
q[i].cnt=y;
}
else if(x==q[i].val)
{
q[i].cnt=(q[i].cnt+y)%mod;
}
return;
}
if(p<=q[i].mid)
update(i*2,p,x,y);
else if(p>q[i].mid)
update(i*2+1,p,x,y);
if(q[i*2].val==q[i*2+1].val)
{
q[i].val=q[i*2].val;
q[i].cnt=(q[i*2].cnt+q[i*2+1].cnt)%mod;
}
else if(q[i*2].val>q[i*2+1].val)
{
q[i].val=q[i*2].val;
q[i].cnt=q[i*2].cnt;
}
else
{
q[i].val=q[i*2+1].val;
q[i].cnt=q[i*2+1].cnt;
}
} int n;
int arr[N];
vector<int>xs;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&arr[i]);
xs.push_back(arr[i]);
}
sort(xs.begin(),xs.end());
auto e=unique(xs.begin(),xs.end());
for(int i=1;i<=n;i++)
arr[i]=lower_bound(xs.begin(), e, arr[i])-xs.begin()+1; build(1,0,n); for(int i=1;i<=n;i++)
{
int x,y;
query(1,0,arr[i]-1,x,y);
// printf("%d %d\n",x,y);
if(!y)
y=1;
update(1, arr[i] , x+1, y);
}
int x,y;
query(1,0,n,x,y);
printf("%d\n",y);
return 0;
}

51nod 1376【线段树维护区间最大值】的更多相关文章

  1. HDU 2795 Billboard 【线段树维护区间最大值&&查询变形】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=2795 Billboard Time Limit: 20000/8000 MS (Java/Others) ...

  2. hdu1754线段树维护区间最大值

    #include <iostream> #include <cstdio> using namespace std; #define MAXN 200005 int N,M; ...

  3. 【HDOJ 1337】I Hate It(线段树维护区间最大值)

    Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写 ...

  4. 洛谷P3113 [USACO14DEC]马拉松赛跑Marathon_Gold 线段树维护区间最大值 模板

    如此之裸- Code: #include<cstdio> #include<cstring> #include<cmath> #include<algorit ...

  5. POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )

    POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...

  6. Can you answer these queries V SPOJ - GSS5 (分类讨论+线段树维护区间最大子段和)

    recursion有一个整数序列a[n].现在recursion有m次询问,每次她想知道Max { A[i]+A[i+1]+...+A[j] ; x1 <= i <= y1 , x2 &l ...

  7. 线段树维护区间前k小

    线段树维护区间前k小 $ solution: $ 觉得超级钢琴太麻烦?在这里线段树提供一条龙服务 . 咳咳,开始讲正题!这道题我们有一个和超级钢琴复杂度一样 $ ~O(~\sum x\times lo ...

  8. CodeForces - 587E[线段树+线性基+差分] ->(线段树维护区间合并线性基)

    题意:给你一个数组,有两种操作,一种区间xor一个值,一个是查询区间xor的结果的种类数 做法一:对于一个给定的区间,我们可以通过求解线性基的方式求出结果的种类数,而现在只不过将其放在线树上维护区间线 ...

  9. FJUT3568 中二病也要敲代码(线段树维护区间连续最值)题解

    题意:有一个环,有1~N编号,m次操作,将a位置的值改为b,问你这个环当前最小连续和多少(不能全取也不能不取) 思路:用线段树维护一个区间最值连续和.我们设出两个变量Lmin,Rmin,Mmin表示区 ...

随机推荐

  1. MVC入门——增

    创建数据库表如下: 生成EF模型 //------------------------------------------------------------------------------ // ...

  2. 九度OJ 1120:全排列 (DFS)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4471 解决:1139 题目描述: 给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列. 我们假设对于小写字母有'a' < ...

  3. 谷歌浏览器使用SelectorGadget和Xpath Helper获取xpath和css path

    在上篇文章里,介绍了如何在火狐浏览器中获取网页元素的xpath和css path. 这篇文章将介绍,在谷歌浏览器中使用SelectorGadget和Xpath Helper实现同样功能. 这两个谷歌浏 ...

  4. Could not get unknown property 'packageForR' for task ':app:processDebugReso

    butterknife 注解框架的问题 删除项目中的有关butterknife 的 apply plgin.classpath 字段 把注解框架改为最新版本 implementation 'com.j ...

  5. RTSP(Real Time Streaming Protocol)学习笔记 -- RFC2326

    Real Time Streaming Protocol (RTSP)  RTSP是用在娱乐或通讯中控制流媒体服务器的网络协议,它可以创建和控制两个端点之间的会话. Client发出一些命令来控制me ...

  6. [bzoj 3720] Gty的妹子树 (树上分块)

    树上分块(块状树) Description 我曾在弦歌之中听过你, 檀板声碎,半出折子戏. 舞榭歌台被风吹去, 岁月深处尚有余音一缕-- Gty神(xian)犇(chong)从来不缺妹子-- 他来到了 ...

  7. LightOJ1370 Bi-shoe and Phi-shoe —— 欧拉函数

    题目链接:https://vjudge.net/problem/LightOJ-1370 1370 - Bi-shoe and Phi-shoe    PDF (English) Statistics ...

  8. 深入理解c语言——‘\0’ ,‘0’, “0” ,0之间的区别

    看来基础还是很重要的,基础不扎实就难以学好c语言,就别说写出高质量的c语言代码了.今天,我就被这个问题折磨的不行了,哈哈,不过现在终于明白了‘\0’ ,‘0’, “0” 之间的区别了.困惑和快乐与你分 ...

  9. Android自动化测试怎么填写Xpath

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA5sAAAJYCAIAAABjAmXpAAAgAElEQVR4nOzdeZhb5Z0veNV/M88sz7 ...

  10. SQL Server中误删除数据的恢复

    SQL Server中误删除数据的恢复本来不是件难事,从事务日志恢复即可.但是,这个恢复需要有两个前提条件: 1. 至少有一个误删除之前的数据库完全备份. 2. 数据库的恢复模式(Recovery m ...