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