Codeforces Testing Round #12 C. Subsequences 树状数组
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+10, M = 5e5+11, inf = 2e9, mod = 998244353; int dp[N][20];// 以i结尾 长度为j的方案数 /* 那么答案就是 dp[i][j] = dp[x][j-1] all a[x] < a[i] ; */ LL C[N][20]; 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 = 0; for(int i = x; i; i -= i&(-i)) { s += C[i][k]; } return s; } int main() { scanf("%d%d",&n,&k); for(int i = 1; i <= n; ++i) scanf("%d",&a[i]); update(a[1],1,1); for(int i = 2; i <= n; ++i) { update(a[i],1,1); for(int j = 1; j <= k; ++j) { LL tmp = query(a[i]-1,j); update(a[i],j+1,tmp); } } LL ans = 0; printf("%I64d\n",query(n,k+1)); return 0; }