题目链接:
time limit per test
1 secondmemory limit per test
256 megabytesinput
standard inputoutput
standard outputFor 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<<" ";//注意k==0的情况 else cout<<ans<<" "; return 0; }