【树状数组】51nod 1376 最长递增子序列的数量

通道

思路:dp[i]由dp[i-1]而来,统计小于a[i]的位置k,且dp[k]+1=dp[i]的所有个数即可。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;

template <class T>
inline bool rd(T &ret) {
    char c; int sgn;
    if(c = getchar() , c == EOF) return false;
    while(c != '-' && (c < '0' || c > '9')) c = getchar();
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while(c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return true;
}
const int MAX_N = 500007;
const int N = MAX_N;
const int MOD = (int)1e9 + 7;

struct Bit {
    int bit[N];
    void clear() {
        memset(bit, 0, sizeof bit);
    }
    void add(int i, int v) {
        for (;i < N; i += i & -i)
            if (v > bit[i]) bit[i] = v;
    }
    int query(int i) {
        int re = 0;
        for (;i > 0; i -= i & -i)
            re = max(re, bit[i]);
        return re;
    }
};

int n;
int a[MAX_N], b[MAX_N], dp[MAX_N];
int pre[MAX_N];

#include <vector>
vector<int> v[MAX_N];

void Main() {
    rd(n);
    for (int i = 0; i < n; ++i) rd(a[i]), b[i] = a[i];
    sort(b, b + n);
    int m = unique(b, b + n) - b;
    for (int i = 0; i < n; ++i) 
        a[i] = lower_bound(b, b + m, a[i]) - b + 2;
    Bit B;
    int ans = 0;
    for (int i = 0; i < n; ++i) {
        dp[i] = B.query(a[i] - 1);
        int now = 0;
        for (int j = 0; j < v[dp[i]].size(); ++j) {
            int u = v[dp[i]][j];
            if (a[u] < a[i]) {
                now = (now + pre[u]) % MOD;
            }
        }
        if (dp[i] == 0) pre[i] = 1;
        else pre[i] = now;
        ans = max(ans, dp[i] + 1);
        v[dp[i] + 1].push_back(i);
        B.add(a[i], dp[i] + 1);
    }
    int res = 0;
    for (int i = 0; i < n; ++i) if (ans == dp[i] + 1)
        res = (res + pre[i]) % MOD;
    printf("%d\n", res);
    return ;
}

int main() {
    Main();
    return 0;
}
View Code

 

posted @ 2015-09-30 16:27  mithrilhan  阅读(458)  评论(1编辑  收藏  举报