牛客练习赛56-C
思路:
先依次预处理每个数字是第几大,然后依次按大小插入到树状数组中,每插入一个数判断现在数组中比当前数小的有多少个,
逐层更新下去,更新到k层,把k层数值加起来即可
#include<iostream> #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; }