CF597C. Subsequences [dp樹狀陣列優化]
阿新 • • 發佈:2019-01-11
題意翻譯
題目描述
輸入一個1~n的排列, 以及一個正整數k, 求該排列種有多少個長度為k+1的上升子序列. 保證答案小於8乘10的18次方.
輸入格式
第一行輸入兩個正整數n和k
接下來n行每行一個正整數描述輸入的排列
輸出格式
輸出一個數表示答案.
題目描述
For the given sequence with nn different elements find the number of increasing subsequences with k+1k+1 elements. It is guaranteed that the answer is not greater than 8·10^{18}8⋅1018 .
輸入輸出格式
輸入格式:
First line contain two integer values nn and kk (1<=n<=10^{5},0<=k<=10)(1<=n<=105,0<=k<=10) — the length of sequence and the number of elements in increasing subsequences.
Next nn lines contains one integer a_{i}ai ( 1<=a_{i}<=n1<=ai<=n ) each — elements of sequence. All values a_{i}aiare different.
輸出格式:
Print one integer — the answer to the problem.
輸入輸出樣例
輸入樣例#1: 複製
5 2 1 2 3 5 4
輸出樣例#1: 複製
7
跟HDOJ5542-The Battle of Chibi【樹狀陣列優化dp】(推薦,詳細介紹)一樣,只不過資料範圍大一點,注意一下dp的大小就行
#include<stdio.h> #include<string> #include<string.h> #include<cstdio> #include<algorithm> #include<iostream> using namespace std; typedef long long ll; const int MAXN=100000+5;//最大元素個數 const int mod=1e9+7; ll m,n;//元素個數 ll c[MAXN]; ll a[MAXN],b[MAXN],dp[15][MAXN];//c[i]==A[i]+A[i-1]+...+A[i-lowbit(i)+1] //返回i的二進位制最右邊1的值 int lowbit(int i) { return i&(-i); } //返回A[1]+...A[i]的和 ll sum(int x){ ll sum = 0; while(x){ sum =sum+c[x]; x -= lowbit(x); } return sum; } //令A[i] += val void add(int x, ll val){ while(x <= n){ c[x] =c[x]+val; x += lowbit(x); } } int main() { while(scanf("%lld%lld",&n,&m)!=-1) { m++; for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); b[i]=a[i]; } sort(b+1,b+n+1); int len=unique(b+1,b+n+1)-(b+1); dp[0][0]=1; for(int i=1;i<=m;i++) { memset(c,0,sizeof(c)); add(1,dp[i-1][0]); //val(a[o])=1 for(int j=1;j<=n;j++) { int pos=lower_bound(b+1,b+n+1,a[j])-b+1; dp[i][j]=sum(pos-1); add(pos,dp[i-1][j]); } } ll ans = 0; for (int i = 1; i <= n; i++) ans = ans + dp[m][i]; printf("%lld\n", ans); } return 0; }