zoukankan      html  css  js  c++  java
  • 【51NOD1376】最长递增子序列的数量

    题面

    数组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。
    1 <= N <= 50000,0 <= Ai <= 10^9

    分析

    记得以前在光华好像有一道题就是算这个,当时就只想着在dp里动手脚,但是正确性不能保证。现在也没啥新想法TAT
    一搜题解,啥,CDQ啊??奇怪的姿势。最后找到了一篇姿势优美的题解,但是思路只有一行。又只有从代码推思路。
    回想n2的dp的做法,f[i]表示以a[i]为结尾的最长上升子序列的长度,我们应该应该找一个在最大的f[j]中找尽量小的j,使j<i并且a[j]<a[i],即可使f[i]=f[j]+1.
    就是找j的这一步,用树状数组优化为logn。

    用树状数组同时维护len和num,表示长度和数量。每次询问a[i]之前树状数组上的的len和num来更新f[i]。只要每一次长度被更新,数量也同步更新。
    注意到a[i]太大了,应该离散化一下才能用树状数组做。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define N 50050
    #define mod 1000000007
    int n,cnt,a[N],tmp[N];
    struct email
    {
        int len,num;
    }ans,f[N],t[N];
    inline int lowbit(int x){return x&(-x);}
    
    inline void dp(email &x,email y)
    {
        if(x.len>y.len)return;
        if(x.len<y.len)x=y;
        else x.num=(x.num+y.num)%mod;
    }
    
    inline email query(int x)
    {
        email ret;ret.len=0,ret.num=1;
        for(;x;x-=lowbit(x))
            dp(ret,t[x]);
        return ret;
    }
    
    inline email add(int x,email y)
    {
        for(;x<=cnt;x+=lowbit(x))
            dp(t[x],y);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),tmp[i]=a[i];
        sort(tmp+1,tmp+1+n);
        cnt=unique(tmp+1,tmp+1+n)-(tmp+1);
        for(int i=1;i<=n;i++)a[i]=lower_bound(tmp+1,tmp+1+cnt,a[i])-tmp;
        for(int i=1;i<=n;i++)f[i]=query(a[i]-1),f[i].len++,add(a[i],f[i]);
        for(int i=1;i<=n;i++)dp(ans,f[i]);
        printf("%d
    ",ans.num);
    }
    “Make my parents proud,and impress the girl I like.”
  • 相关阅读:
    CCF NOI1062 计算曼哈顿距离
    CCF NOI1061 Wifi密码
    CCF NOI1073 放苹果
    CCF NOI1072 爬楼梯
    CCF NOI1071 Pell数列
    CCF NOI1064 计算斐波那契第n项
    NOI训练行动路线图
    CCF NOI1060 雷同检测
    CCF NOI1059 表达式求值
    CCF NOI1057 石头剪刀布
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9803435.html
Copyright © 2011-2022 走看看