• [TJOI2014]上升子序列


    Description

    BZOJ5157
    Luogu3970
    求原序列有多少个上升子序列。

    Solution

    本来想先暴力DP一下拿个部分分,但是由于不会去重,这个思路就破灭了。
    后来手玩的时候突然发现,不就是把比这个数小的答案都加起来就是它的答案了啊,形式化的说就是(f_i=sum f_j (j < i,a_j<a_i))
    这样的话离散化一下树状数组求前缀和就可以水过了...

    Code

    #include <cstdio>
    #include <algorithm>
    
    const int N = 1e5 + 10;
    const int MOD = 1e9 + 7;
    
    int f[N], a[N], b[N], n, c[N];
    
    void add(int p, int x) {
        while (p <= n) {
            f[p] = (f[p] + x) % MOD;
            p += p&-p;
        }
    }
    
    int query(int p) {
        int ans = 0;
        while (p > 0) {
            ans = (ans + f[p]) % MOD;
            p -= p&-p;
        }
        return ans;
    }
    
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
            c[i] = a[i];
        }
        std::sort(c+1, c+n+1);
        int now = std::unique(c+1, c+n+1) - c;
        for (int i = 1; i <= n; ++i) {
            b[i] = std::lower_bound(c+1, c+now, a[i]) - c;
        }
        for (int i = 1; i <= n; ++i) {
            int ans = query(b[i]-1)+1;
            add(b[i], (query(b[i])-query(b[i]-1)+MOD)%MOD*-1);
            add(b[i], ans);
        }
        int ans = (query(n) - now + 1 + MOD) % MOD;
        printf("%d
    ", ans);
        return 0;
    }

    转载于:https://www.cnblogs.com/wyxwyx/p/lg3940.html

  • 相关阅读:
    LintCode: Climbing Stairs
    LintCode: Binary Tree Postorder Traversal
    LintCode: Binary Tree Preorder Traversal
    LintCode: Binary Tree Inorder Traversal
    Lintcode: Add Two Numbers
    Lintcode: Add Binary
    LintCode: A + B Problem
    LintCode: Remove Linked List Elements
    LintCode:Fibonacci
    Lintcode开刷
  • 原文地址:https://www.cnblogs.com/twodog/p/12135968.html
Copyright © 2020-2023  润新知