zoukankan      html  css  js  c++  java
  • [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

  • 相关阅读:
    旅行计划
    两只塔姆沃斯牛
    迷宫
    异或序列
    异或之和
    素数个数
    SAC E#1
    [JSOI2010]Group 部落划分 Group
    [USACO12FEB]附近的牛Nearby Cows
    [HNOI2008]Cards
  • 原文地址:https://www.cnblogs.com/twodog/p/12135968.html
Copyright © 2011-2022 走看看