Codeforces 597C 子序列

题面

【题目描述】

给你一个包含n个不同元素的序列,让你求出在这个序列中有多少个长度为k+1的上升子序列。保证答案不会超过8*10^18。

【输入描述】

第一行包括两个正整数n和k(1<=n<=10^5,0<=k<=10)
接下来n行每行包括一个正整数ai(1<=ai<=n),所有ai都是不同的。

【输出描述】

输出一个整数,表示这个问题的答案。

【样例输入】

5 2
1
2
3
5
4

【样例输出】

7

题解

树状数组优化(O(kn log n))求不下降子序列数.
算是补了ISN那一道题的坑吧.

 
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
 
namespace Zeonfai
{
    inline long long getInt()
    {
        long long a = 0, sgn = 1;
        char c;
        while(! isdigit(c = getchar()))
            if(c == '-')
                sgn *= -1;
        while(isdigit(c))
            a = a * 10 + c - '0', c = getchar();
        return a * sgn;
    }
}
const long long N = (long long)1e5;
struct binaryIndexTree
{
    long long a[N + 1];
    inline void clear()
    {
        memset(a, 0, sizeof(a));
    }
    inline void modify(long long u, long long dta, long long bnd)
    {
        for(; u <= bnd; u += u & - u)
            a[u] += dta;
    }
    inline long long query(long long u)
    {
        long long res = 0;
        for(; u; u -= u & -u)
            res += a[u];
        return res;
    }
}BIT;
int main()
{
 
    #ifndef ONLINE_JUDGE
    freopen("CF597C.in", "r", stdin);
    #endif
 
    using namespace Zeonfai;
    long long n = getInt(), k = getInt();
    static long long a[N];
    for(long long i = 0; i < n; ++ i)
        a[i] = getInt();
    static long long f[N];
    for(long long i = 0; i < n; ++ i)
        f[i] = 1;
    for(long long i = 0; i < k; ++ i)
    {
        BIT.clear();
        for(long long j = 0; j < n; ++ j)
            BIT.modify(a[j], f[j], n), f[j] = BIT.query(a[j] - 1);
    }
    long long ans = 0;
    for(long long i = 0; i < n; ++ i)
        ans += f[i];
    printf("%lld", ans);
}
原文地址:https://www.cnblogs.com/ZeonfaiHo/p/7153593.html