Milthm
2024-11-17 20:38:53
如你所见,这是一道 diff 为
你十分惊慌,恐怕这道题你根本就无法做出来,马上就要面临着 rating
你冷静地思考了一会,发现这是你最擅长的逆序对题目,你逐渐有了一些自信。
你发现如果把序列分成三段:
前面这一步可以用树状数组快速解决,但是区间的期望逆序对数量该如何求出?
在耀眼的光芒中,你看见了可爱的 lxy,她只给了你六个字符 CF749E,让你自己领会。
在艰难的探索中,你终于发现,因为两个数形成逆序对的概率是
你非常高兴,很快就打出了一份代码,它十分的正确,仅一遍就通过了样例,并获得了一个绿色的 AC。
#include<bits/stdc++.h>
#define int long long
#define N 200005
using namespace std;
const int mod=998244353;
int n,k,a[N],sum,now,ans;
struct BIT{
int c[N];
void add(int x,int k){while(x<=n)c[x]+=k,x+=x&-x;}
int ask(int x){int ans=0;while(x)ans+=c[x],x-=x&-x;return ans;}
void clear(){memset(c,0,sizeof(c));}
}A;
int inv(int x,int y=mod-2){
int ans=1;
while(y){
if(y&1)ans=ans*x%mod;
x=x*x%mod;y>>=1;
}
return ans;
}
signed main(){
cin>>n>>k;
for(int i=1;i<=n;++i)cin>>a[i];
for(int i=n;i>=1;--i)sum+=A.ask(a[i]),A.add(a[i],1);
A.clear();
for(int i=k;i>=1;--i)now+=A.ask(a[i]),A.add(a[i],1);
ans=sum-now;
for(int i=1;i<=n-k;++i){
A.add(a[i],-1);
now-=A.ask(a[i]);now+=A.ask(n)-A.ask(a[i+k]);
A.add(a[i+k],1);ans=(ans+sum-now)%mod;
}
cout<<(ans*inv(n-k+1)+k*(k-1)%mod*inv(4))%mod;
return 0;
}
你醒过来,原来这一切都是梦。
你根本就没有看 G,而是被 F 卡了半个多小时,注定只能获得一个失败的青色 perf。