牛客练习赛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
",anss);
    return 0;
}
原文地址:https://www.cnblogs.com/lusiqi/p/12242662.html