列表

详情


NC236324. Robotic Girl

描述

> [Link](https://music.163.com/#/song?id=404783323)

云浅有一个长为 n 的序列 a

她发现逆序对会产生能量,因此她定义: F_0(l,r) 为区间 内的逆序对个数。

形式化地,F_0(l,r) 被定义为满足 的数对 (i,j) 的个数。

经过研究,云浅认为逆序对的能量会产生叠加,因此她定义



给定 k,她希望求出 的值。

输入描述

本题有多组数据。 第一行一个正整数 T 表示数据组数。对于每组数据:

第一行两个正整数 n,k

第二行 n 个正整数 表示云浅的序列。

输出描述

对于每组数据,输出一行一个正整数表示答案。

示例1

输入:

2
4 1
1 3 2 4
6 114514
1 1 4 5 1 4

输出:

4
762789301

说明:

对于第一组数据,F_0(1,3)=F_0(1,4)=F_0(2,3)=F_0(2,4)=1,其余均为 0。故答案为 4

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 908ms, 内存消耗: 19208K, 提交时间: 2022-04-30 20:50:08

#include<bits/stdc++.h>
#define VI vector<int>
#define II pair<int,int>
#define mp make_pair
using namespace std;
typedef long long ll;
typedef double db;
const int N=3e5+5;
const int md=998244353;

int n,m,a[N],id[N];
int cnt[N];
ll ans,fac[N*2],inv[N*2],inf[N*2],t[N];
ll Com(int x, int y){
    return fac[x]*inf[y]%md*inf[x-y]%md;
}
void upd(int x, ll y){
    for (; x<=n; x+=x&-x) (t[x]+=y)%=md;
}
ll calc(int x, ll res=0){
    for (; x; x-=x&-x) (res+=t[x])%=md;
    return res;
}
bool cmp(int x, int y){
    return a[x]==a[y]? (x>y):(a[x]>a[y]);
}
void solve(){
    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; ++i) {
        id[i]=i;
        scanf("%d",&a[i]);
    }
    sort(id+1,id+n+1,cmp);
    ll ans=0;
    for (int i=1; i<=n; ++i){
        (ans+=Com(n-id[i]+m,m)*calc(id[i])%md)%=md;
        upd(id[i],Com(id[i]+m-1,m));
    }
    for (int i=1; i<=n; ++i) t[i]=0;
    printf("%lld\n",ans);
}
void init(){
    fac[0]=fac[1]=inv[1]=inv[0]=inf[0]=inf[1]=1;
    for (int i=2; i<=600000; ++i){
        fac[i]=fac[i-1]*i%md;
        inv[i]=(md-md/i)*inv[md%i]%md;
        inf[i]=inf[i-1]*inv[i]%md;
    }
}
int main(){
    int T=1;
    init();
    scanf("%d",&T);
    while (T--){
        solve();
    }
}

上一题