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;
}

 

  

posted @ 2016-08-13 10:34  meekyan  阅读(229)  评论(0编辑  收藏  举报