题面
【题目描述】
给你一个包含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);
}