Light OJ 1085 - All Possible Increasing Subsequences

时间:2022-11-18 19:30:21

题目

link
给定一个序列, 求出上升子序列的总数。

分析

Dp[i] 表示序列 以 i 结尾的数目。
可知 Dp[i]=Dp[x]+1
这是一个前缀和, 用树状数组维护。

Code

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int maxn = 1e5 + 131;
const LL MOD = 1e9 + 7;

LL Num[maxn], A[maxn], B[maxn];
int n;
int lowebit(int x) { return x&(-x); }
LL Sum(int x) {
    LL ret = 0;
    while(x > 0)
    {
        ret = (ret + Num[x]) % MOD;
        x -= lowebit(x);
    }
    return ret;
}
void Update(int x, LL Val) {
    while(x <= n)
    {
        Num[x] = (Num[x] + Val) % MOD;
        x += lowebit(x);
    }
}

int main()
{
    int t;
    scanf("%d",&t);
    for(int kase = 1; kase <= t; ++kase)
    {
        scanf("%d",&n);
        memset(Num, 0, sizeof(Num));
        for(int i = 0; i < n; ++i)
            scanf("%lld",A+i), B[i] = A[i];
        sort(A, A+n);
        int Max = unique(A, A+n)-A;
        for(int i = 0; i < n; ++i)
        {
            B[i] = lower_bound(A, A+Max, B[i])-A + 1;
        }
        //cout << "1" <<endl;
        for(int i = 0; i < n; ++i)
        {
            LL s = Sum(B[i]-1) + 1;
            //cout << "2" << " " <<B[i] <<endl;
            s %= MOD;
            Update(B[i], s);
            //cout << "3" <<endl;
        }
        LL Ans = Sum(n);
        printf("Case %d: %lld\n",kase, Ans);
    }
    return 0;
}