CodeForces - 597C Subsequences (树状数组+动态规划)

For the given sequence with n different elements find the number of increasing subsequences with k + 1elements. 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 + 1 个元素的递增子序列有多少个。数据保证:答案不超过 8·1018 。
思路:
dp[a[i]][k]表示以a[i]为结尾,长度为k的子序列的个数.
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define ls (t<<1)
#define rs ((t<<1)+1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 100086;
const int inf = 2.1e9;
const ll Inf = 999999999999999999;
const int mod = 1000000007;
const double eps = 1e-6;
const double pi = acos(-1);

int a[maxn];
ll dp[maxn][15];

ll bit[maxn][15];
int lowbit(int x){
    return x&-x;
}

void update(int pos,ll val,int t){
    while(pos<maxn){
        bit[pos][t]+=val;
        pos+=lowbit(pos);
    }
}

ll query(int pos,int t){
    ll ans=0;
    while(pos){
        ans+=bit[pos][t];
        pos-=lowbit(pos);
    }
    return ans;
}

int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    k++;

    update(1,1,0);

    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        a[i]++;
        for(int j=1;j<=k;j++){
            ll ans=query(a[i]-1,j-1);//a[i]-1防止自己接自己
            dp[a[i]][j]=ans;
            update(a[i],dp[a[i]][j],j);
        }
    }
    ll ans=0;
    for(int i=1;i<=n+1;i++){
        ans+=dp[i][k];
    }
    printf("%lld\n",ans);


    return 0;
}
View Code

 

posted @ 2019-04-17 22:33  断腿三郎  阅读(286)  评论(0编辑  收藏  举报