1. 程式人生 > >CF597C. Subsequences [dp樹狀陣列優化]

CF597C. Subsequences [dp樹狀陣列優化]

題意翻譯

題目描述

輸入一個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}ai​are 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;
}