CF597C. Subsequences [dp树状数组优化]

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sdz20172133/article/details/86295025

题意翻译

题目描述

输入一个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;
}

猜你喜欢

转载自blog.csdn.net/sdz20172133/article/details/86295025