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

不过树状数组一直不怎么会用。。。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define clr(x,c) memset(x,c,sizeof(x))
#define lson l,mid,x<<1
#define rson mid+1,r,x<<1|1
int read(){
int x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x;
}
const int nmax=5e4+5;
const int inf=0x7f7f7f7f;
const int mod=1e9+7;
int a[nmax],b[nmax],mx[nmax<<2],sm[nmax<<2];
int qmax(int tl,int tr,int l,int r,int x){
if(tl<=l&&tr>=r) return mx[x];
int mid=(l+r)>>1,ans=0;
if(tl<=mid) ans=max(ans,qmax(tl,tr,lson));
if(tr>mid) ans=max(ans,qmax(tl,tr,rson));
return ans;
}
int query(int tl,int tr,int p,int l,int r,int x){
if(tl<=l&&tr>=r) return mx[x]==p?sm[x]:0;
int mid=(l+r)>>1,ans=0;
if(tl<=mid) ans+=query(tl,tr,p,lson);
if(tr>mid) ans+=query(tl,tr,p,rson);
return ans>=mod?ans-mod:ans;
}
void update(int p,int a,int b,int l,int r,int x){
if(mx[x]<a) mx[x]=a,sm[x]=b;
else if(mx[x]==a) sm[x]=(sm[x]+b)%mod;
if(l==r) return ;
int mid=(l+r)>>1;
p<=mid?update(p,a,b,lson):update(p,a,b,rson);
}
void print(int l,int r,int x){
printf("%d %d:%d %d\n",l,r,mx[x],sm[x]);
if(l==r) return ;
int mid=(l+r)>>1;
print(lson);print(rson);
}
int main(){
int n=read();rep(i,1,n) a[i]=b[i]=read();
sort(b+1,b+n+1);int cnt=unique(b+1,b+n+1)-b-1;
rep(i,1,n) a[i]=lower_bound(b+1,b+cnt+1,a[i])-b;
int u,v,d;
rep(i,1,n){
u=a[i]==1?1:qmax(1,a[i]-1,1,cnt,1)+1;
v=u==1?1:query(1,a[i]-1,u-1,1,cnt,1);
update(a[i],u,v,1,cnt,1);
/*printf("->%d %d\n",u,v);
printf("->_->\n");print(1,cnt,1);*/
}
printf("%d\n",sm[1]);
return 0;
}

  

基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题
 收藏
 关注
数组A包含N个整数(可能包含相同的值)。设S为A的子序列且S中的元素是递增的,则S为A的递增子序列。如果S的长度是所有递增子序列中最长的,则称S为A的最长递增子序列(LIS)。A的LIS可能有很多个。例如A为:{1 3 2 0 4},1 3 4,1 2 4均为A的LIS。给出数组A,求A的LIS有多少个。由于数量很大,输出Mod 1000000007的结果即可。相同的数字在不同的位置,算作不同的,例如 {1 1 2} 答案为2。
Input
第1行:1个数N,表示数组的长度。(1 <= N <= 50000)
第2 - N + 1行:每行1个数A[i],表示数组的元素(0 <= A[i] <= 10^9)
Output
输出最长递增子序列的数量Mod 1000000007。
Input示例
5
1
3
2
0
4
Output示例
2

51nod1376 最长递增子序列的数量的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. 673. Number of Longest Increasing Subsequence最长递增子序列的数量

    [抄题]: Given an unsorted array of integers, find the number of longest increasing subsequence. Exampl ...

  7. 51nod1376 最长上升子序列的数量

    机房的人问我树状数组怎么做这题...... 树状数组维护$len, num$表示$LIS$的长度和数量即可 复杂度$O(n \log n)$ 注:$O(n \log n)$二分+单调栈才是真神仙 具体 ...

  8. 51nod 1376 最长递增子序列的数量(不是dp哦,线段树 +  思维)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1376 题解:显然这题暴力的方法很容易想到就是以每个数为结尾最 ...

  9. 【动态规划】拦截导弹_dilworth定理_最长递增子序列

    问题 K: [动态规划]拦截导弹 时间限制: 1 Sec  内存限制: 256 MB提交: 39  解决: 10[提交][状态][讨论版] 题目描述 张琪曼:“老师,修罗场是什么?” 墨老师:“修罗是 ...

随机推荐

  1. 安装微软ASP.NET MVC 4,运行以下的包管理器控制台命令

    (菜鸟,勿喷,有错求指正)Asp.net  新建的类库中安装MVC4  .下面是步骤,1+2:打开程序包管理控制台,3:运行Install-Package Microsoft.AspNet.Mvc - ...

  2. ExtJs布局之border

    <!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...

  3. Codeforces Round #336 (Div. 2) A. Saitama Destroys Hotel 模拟

    A. Saitama Destroys Hotel   Saitama accidentally destroyed a hotel again. To repay the hotel company ...

  4. 在 eclipse 中设置每行的字数

    在Preferences中:Java Code Style Formatter

  5. Project Euler P105:Special subset sums: testing 特殊的子集和 检验

    Special subset sums: testing Let S(A) represent the sum of elements in set A of size n. We shall cal ...

  6. java隐士类型转换和强制类型转换

    ,byte和short型在计算时会自动转换为int型计算,结果也是int 型.所以a1*a2的结果是int 型的. byte+byte=int,低级向高级是隐式类型转换,高级向低级必须强制类型转换,b ...

  7. SWD应用接口

    随着ARM公司对Cortex系列的推出,采样SWD方式调试成了大家的首选.SWD不仅速度可以与JTAG媲美,而且使用的调试线少得多.很多人在采样SWD方式进行调试时,一般都是采用4线: ① VCC   ...

  8. android-exploitme(四):参数篡改

    今天我们来测试请求中参数的篡改,这个在web安全测试中是常用的,拦截请求包,修改参数,提交 1.  首先我们需要启动模拟器,并使用本机的代理(加上参数-partition-size的目的是为了可以往a ...

  9. CreateProcess启动隐藏的外部程序(其实就是CreateDesktop,然后指定STARTUPINFO.lpDesktop)

    HDESK hDesk = CreateDesktop(_T("MyDesk"), NULL, NULL, 0, GENERIC_ALL, NULL); ASSERT(hDesk) ...

  10. Android笔记——Handler更新UI示例

    public class MainActivity extends ActionBarActivity { private TextView textView; private int i=0; @O ...