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


    机房的人问我树状数组怎么做这题......

    树状数组维护$len, num$表示$LIS$的长度和数量即可

    复杂度$O(n log n)$

    注:$O(n log n)$二分+单调栈才是真神仙

    具体看代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    extern inline char gc() {
        static char RR[23456], *S = RR + 23333, *T = RR + 23333;
        if(S == T) fread(RR, 1, 23333, stdin), S = RR;
        return *S ++;
    }
    inline int read() {
        int p = 0, w = 1; char c = gc();
        while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
        while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
        return p * w;
    }
    
    #define mod 1000000007
    #define ri register int
    #define sid 50050
    
    int n, cnp, H[sid], a[sid];
    struct aha {
        int len, num;
    } t[sid], f[sid];
    
    void upd(aha &x, aha y) {
        if(x.len > y.len) return;
        if(x.len < y.len) x = y;
        else x.num += y.num, x.num %= mod;
    }
    
    aha qry(int x) {
        aha ret = { 0, 1 };
        for(ri i = x; i; i -= i &(-i)) upd(ret, t[i]);
        return ret;
    }
    
    aha add(int x, aha v) {
        for(ri i = x; i <= cnp; i += i & (-i)) upd(t[i], v);
    }
    
    int main() {
        n = read();
        for(ri i = 1; i <= n; i ++) a[i] = H[i] = read();
        sort(H + 1, H + n + 1);
        cnp = unique(H + 1, H + n + 1) - H - 1;
        for(ri i = 1; i <= n; i ++) a[i] = lower_bound(H + 1, H + cnp + 1, a[i]) - H;
        for(ri i = 1; i <= n; i ++) {
            f[i] = qry(a[i] - 1); f[i].len ++;
            add(a[i], f[i]);
        }
        aha ans = { 0, 0 };
        for(ri i = 1; i <= n; i ++) upd(ans, f[i]);
        printf("%d
    ", ans.num);
        return 0;
    }
  • 相关阅读:
    Linux 安装nginx
    Linux服务器svn与项目同步
    Linux服务器安装svn
    Thinkphp5模板继承
    Thinkphp5 Route用法
    一键切换hosts文件
    lnmp手动新建虚拟机
    wamp 配置虚拟主机
    百度编辑器
    百度编辑器:上传图片二
  • 原文地址:https://www.cnblogs.com/reverymoon/p/9496040.html
Copyright © 2020-2023  润新知