牛客练习赛56-C

C 小魂和他的数列在这里插入图片描述

预处理出该序列中的每个数是第几大的,然后依次按照大小插入到树状数组中,
没插入一个数字,就判断现在在数组中的数比当前数小的数有多少个,让后逐层更新一下,更新k层,最后把低K层的数加起来即可。

#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=600500;
const ll mod=998244353;
ll c[N][15],ans[N][15];
int a[N],b[N];
int n,k;
void add(int i,int x,int y) {
	for(; x<=n; x+=x&-x)
		c[x][i]=(c[x][i]+y)%mod;
}
ll ask(int i,int x) {
	ll ans=0;
	for(; x; x-=x&-x)ans=(ans+c[x][i])%mod;
	return ans;
}
int main() {
	scanf("%d %d",&n,&k);
	for(int i=1; i<=n; ++i) {
		scanf("%d",&a[i]);
		b[i]=a[i];
	}
	sort(b+1,b+n+1);
	int len=unique(b+1,b+n+1)-b-1;
	for(int i=1; i<=n; ++i) {
		a[i]=lower_bound(b+1,b+len+1,a[i])-b;
	}
	ll anss=0;
	for(int i=1; i<=n; ++i) {
		add(1,a[i],1);
		for(int j=2; j<=min(i,k); ++j) {
			ans[i][j]=ask(j-1,a[i]-1);
			add(j,a[i],ans[i][j]);
		}
		anss=(anss+ans[i][k])%mod;
	}
	printf("%lld\n",anss);
	return 0;
}

好狠一道题,活生生改了我一上午,同样的代码,同时交好几发,三分之一过,三分之二超时,最后把二维数组的的两个维度换一下,快了将近一半时间,不知道是玄学还是有什么依据,太菜了啊。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值