题解:[ARC154E] Reverse and Inversion
前言
好题。
思路分析
这个题分为很多部分,各个部分之间比较独立。
我们一点一点来。
首先考虑 \(f(p)\) 怎么算。
把贡献拆到每一个点上,发现:
\[f(p)=\sum_{i=1}^{n}i(\sum_{j=1}^{i-1} [p_i<p_j]-\sum_{i=j+1}^{n}[p_j<p_i])
\]
然后对后面做一点变换:
\[f(p)=\sum_{i=1}^{n}i(i-\sum_{j=1}^{i}[p_i\ge p_j] -\sum_{i=j+1}^{n}[p_i \ge p_j])
\]
\[f(p)=\sum_{i=1}^{n}i(i-\sum_{j=1}^{n}[p_i\ge p_j])
\]
\[f(p)=\sum_{i=1}^{n}i(i-p_i)
\]
\[f(p)=\sum_{i=1}^{n}i^2-ip_i
\]
到这里应该非常好了。
\(\sum_{i=1}^{n}i^2\) 是简单的,考虑 \(ip_i\) 怎么做。
我们转化为概率,那么就是等概率选择一个区间翻转,求 \(p_i\) 所在位置的期望,记为 \(s_i\)。
发现,经过一次操作后,\(p_i\) 在 \(j\) 的方案数为 \(\min(i,n-i+1,n-j+1)\)。
所以 \(p_i\) 到 \(j\) 的概率和 \(p_i\) 到 \(n-j+1\) 的概率是相同的。
所以只要 \(p_i\) 被翻转过一次,那么它所在位置的期望就是 \(\frac{n+1}{2}\)。
考虑 \(s_i\) 的计算:
\[p=(1-\frac{2i(n-i+1)}{n(n+1)})^m
\]
\[s_i=ip+\frac{n+1}{2}(1-p)
\]
求出 \(s_i\) 后,我们考虑原问题的答案为:
\[(\frac{n(n+1)}{2})^m\sum_{i=1}^{n}(i^2+s_ip_i)
\]
复杂度 \(O(n \log v)\)。
代码实现
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=998244353;
int binpow(int a,int b){
if(!b) return 1;
int res=binpow(a,b/2);
if(b&1) return res*res%mod*a%mod;
else return res*res%mod;
}
int n,m,q,ans,a[200005];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
ans=n*(n+1)%mod*(2*n+1)%mod*binpow(6,mod-2)%mod;
for(int i=1;i<=n;i++){
q=binpow((1-2*i*(n-i+1)%mod*binpow(n*(n+1)%mod,mod-2)%mod+mod)%mod,m)%mod;
ans=(ans-(q*i%mod+(1-q)*(n+1)%mod*binpow(2,mod-2)%mod)%mod*a[i]%mod+mod)%mod;
}
cout<<ans*binpow(n*(n+1)%mod*binpow(2,mod-2)%mod,m)%mod;
return 0;
}

浙公网安备 33010602011771号