题目链接:

C. Subsequences

time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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·10^18.

 

Input
 

First line contain two integer values n and k (1 ≤ n ≤ 10^5, 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个数的递增子序列的个数是多少;

思路:
  
k不大n也不大看起来好像是dp,假设dp[i][j]表示在前i个数中长度为j的递增子序列并且a[i]是这个序列的最后一位的个数;
   ans[j]=dp[1][j]+dp[2][j]+...+dp[n][j];
   dp[i][j]=dp[x][j-1](x为按a[]序列中数值比它小且在它前面的)
举一个例子:第一行为输入的a[]第二行为最后一个为递增子序列且最后位为a[i]的个数,再把第二行做成一个树状数组再查询,k-1次后就得到结果
6 10 9 7 1 2 8 5 4 3 ans
0 1 1 1 0 1 4 2 2 2 14
0 0 0 0 0 0 2 1 1 1 5

AC代码:
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+4;
int a[N],n,k;
long long dp[N],sum[N],b[N];
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,long long num)
{
    while(x<=n)
    {
        sum[x]+=num;
        x+=lowbit(x);
    }
}
long long query(int x)
{
    long long s=0;
    while(x>0)
    {
        s+=sum[x];
        x-=lowbit(x);
    }
    return s;
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        b[i]=1;
        scanf("%d",&a[i]);
        dp[i]=query(a[i]);
        update(a[i],b[i]);
    }
    for(int i=2;i<=k;i++)
    {
        memset(sum,0,sizeof(sum));
        for(int j=1;j<=n;j++)
        {
            b[j]=dp[j];
            dp[j]=query(a[j]);
            update(a[j],b[j]);
        }
    }
    long long ans=0;
    for(int i=1;i<=n;i++)
    {
        ans+=dp[i];
    }
    if(!k)cout<<n<<"\n";//注意k==0的情况
    else cout<<ans<<"\n";
    return 0;
}