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

做法类似上个题.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1000000007;
int dp[50010][2],a[50010];
struct Tree
{
        int l,r,val,mx;
}tree[50000<<2];
void create(int l,int r,int k)
{
        tree[k].l=l;
        tree[k].r=r;
        tree[k].val=0;
        tree[k].mx=-1;
        if(l==r)
                return;
        int m=l+r>>1;
        create(l,m,k<<1);
        create(m+1,r,k<<1|1);
}
Tree ret;
void seek(int l,int r,int k)
{
        if(l==tree[k].l&&r==tree[k].r)
        {
                if(tree[k].mx>ret.mx)
                        ret=tree[k];
                else if(tree[k].mx==ret.mx)
                        ret.val=(ret.val+tree[k].val)%mod;
                return;
        }
        int m=tree[k].l+tree[k].r>>1;
        if(r<=m)
                seek(l,r,k<<1);
        else if(l>m)
                seek(l,r,k<<1|1);
        else
        {
                seek(l,m,k<<1);
                seek(m+1,r,k<<1|1);
        }
}
void update(int x,int val,int len,int k)
{
        if(tree[k].l==tree[k].r)
        {
                if(tree[k].mx==len)
                        tree[k].val=(tree[k].val+val)%mod;
                else if(tree[k].mx<len)
                        tree[k].mx=len,tree[k].val=val;
                return;
        }
        int m=tree[k].l+tree[k].r>>1;
        if(x<=m)
                update(x,val,len,k<<1);
        else
                update(x,val,len,k<<1|1);
        if(tree[k<<1].mx>tree[k<<1|1].mx)
                tree[k].mx=tree[k<<1].mx,tree[k].val=tree[k<<1].val;
        else if(tree[k<<1].mx<tree[k<<1|1].mx)
                tree[k].mx=tree[k<<1|1].mx,tree[k].val=tree[k<<1|1].val;
        else
                tree[k].mx=tree[k<<1].mx,tree[k].val=(tree[k<<1].val+tree[k<<1|1].val)%mod;
}
map<int,int>mp;
map<int,int>::iterator it;
int main()
{
      freopen("in","r",stdin);
        int n,m=0;
        cin>>n;
        for(int i=0;i<n;i++)
        {
                scanf("%d",a+i);
                mp[a[i]];
        }
        for(it=mp.begin();it!=mp.end();it++)
                it->second=++m;
        create(0,m,1);
        for(int i=0;i<n;i++)
        {
                ret.mx=-1;
                seek(0,mp[a[i]]-1,1);
                if(ret.mx==-1)
                {
                        dp[i][0]=dp[i][1]=1;
                        update(mp[a[i]],1,1,1);
                        if(i>0)
                        {
                                if(dp[i][0]==dp[i-1][0])
                                        dp[i][1]=(dp[i][1]+dp[i-1][1])%mod;
                                else if(dp[i][0]<dp[i-1][0])
                                        dp[i][0]=dp[i-1][0],dp[i][1]=dp[i-1][1];
                        }
                        continue;
                }
                ret.mx++;
                update(mp[a[i]],ret.val,ret.mx,1);
                if(ret.mx>dp[i-1][0])
                        dp[i][0]=ret.mx,dp[i][1]=ret.val;
                else if(ret.mx==dp[i-1][0])
                        dp[i][0]=ret.mx,dp[i][1]=(dp[i-1][1]+ret.val)%mod;
                else
                        dp[i][0]=dp[i-1][0],dp[i][1]=dp[i-1][1];
        }
        cout<<dp[n-1][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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值