Codeforces Testing Round #12 C. Subsequences 树状数组

时间:2021-12-11 21:00:41
C. Subsequences
 
 

For the given sequence with n different elements find the number of increasing subsequences with k + 1 elements. It is guaranteed that the answer is not greater than 8·1018.

Input
 

First line contain two integer values n and k (1 ≤ n ≤ 105, 0 ≤ k ≤ 10) — the length of sequence and the number of elements in increasing subsequences.

Next n lines contains one integer ai (1 ≤ ai ≤ n) each — elements of sequence. All values ai are different.

Output
 

Print one integer — the answer to the problem.

Examples
input
 
5 2
1
2
3
5
4
output
7

题意:

  给你 一个 长度n 的数组 ,k,问你 长度k+1的子序列 有多少

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std; #pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair typedef long long LL;
const long long INF = 1e18;
const double Pi = acos(-1.0);
const int N = 1e5+, M = 5e5+, inf = 2e9, mod = ; int dp[N][];// 以i结尾 长度为j的方案数
/*
那么答案就是
dp[i][j] = dp[x][j-1] all a[x] < a[i] ;
*/
LL C[N][];
int n,k,a[N];
void update(int x,int k,LL c) {
for(int i = x; i < N; i += i&(-i)) {
C[i][k] += c;
}
}
LL query(int x,int k) {
LL s = ;
for(int i = x; i; i -= i&(-i)) {
s += C[i][k];
}
return s;
}
int main() {
scanf("%d%d",&n,&k);
for(int i = ; i <= n; ++i) scanf("%d",&a[i]);
update(a[],,);
for(int i = ; i <= n; ++i) {
update(a[i],,);
for(int j = ; j <= k; ++j) {
LL tmp = query(a[i]-,j);
update(a[i],j+,tmp);
}
}
LL ans = ;
printf("%I64d\n",query(n,k+));
return ;
}