P4223 期望逆序对 题解
大分讨题。
期望 \(\times {n\choose 2}^k\),即求每种情况的逆序对数之和。
考虑枚举所有 \(i<j\) 计算最终 \(a_i>a_j\) 的方案数。记 \(A=a_i,B=a_j\),\(C\) 表示除了 \(a_i,a_j\) 以外的任意一个数,发现最终 \((a_i,a_j)\) 只有 \(7\) 种情况:
\((A,B),(A,C),(B,C),(C,A),(C,B),(B,A),(C,C)\)。
容易得到一个 \(7\times 7\) 的转移矩阵,快速幂求出 \((A,B)\) 转移到每种情况的方案数。接下来枚举 \(i<j\land a_i<a_j\) 考虑每种情况的贡献(\(a_i>a_j\) 类似):
- \((A,B)\):无贡献。
- \((A,C)\):\(C\) 可取 \([1,a_i-1]\) 中的任意一数,贡献为 \(\frac{a_i-1}{n-2}\)。
- \((B,C)\):\(C\) 可取 \([1,b_j-1]\) 中除了 \(a_i\) 的任意一数,贡献为 \(\frac{b_j-2}{n-2}\)。
- \((C,A)\):同理 \(\frac{n-a_i-1}{n-2}\)。
- \((C,B)\):同理 \(\frac{n-b_j}{n-2}\)。
- \((B,A)\):一定为逆序对,贡献为 \(1\)。
- \((C,C)\):\(>\) 和 \(<\) 的对数相等,贡献为 \(\frac 1 2\)。
考虑将 \(i\) 和 \(j\) 的贡献分开算,发现对于一个指定的 \(i\),只需要知道前后 \(>a_i\) 和 \(<a_i\) 的个数就能求出贡献,树状数组维护即可。
时间复杂度 \(\mathcal O(n\log n+\log k)\)。
参考代码:
#include<bits/stdc++.h>
#define ll long long
#define mxn 500003
#define md 1000000007
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define rept(i,a,b) for(int i=a;i<b;++i)
#define drep(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
inline int read(){
int x=0;char c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x;
}
struct node{
ll a[8][8];
inline void init(){
memset(a,0,sizeof(a));
rep(i,1,7)a[i][i]=1;
}
inline node operator*(node x){
node s;
rep(i,1,7)rep(j,1,7)s.a[i][j]=0;
rep(i,1,7)rep(k,1,7)if(a[i][k])
rep(j,1,7)s.a[i][j]=(s.a[i][j]+a[i][k]*x.a[k][j])%md;
return s;
}
}s,d,bs;
int n,k,q,a[mxn],c[mxn];
ll ans,n2,ni,cc,f[8];
inline ll pw(ll x,ll y){
ll s=1;
for(;y;y>>=1){
if(y&1)s=s*x%md;
x=x*x%md;
}
return s;
}
inline void power(int k){
s.init(),bs=d;
for(;k;k>>=1){
if(k&1)s=s*bs;
bs=bs*bs;
}
}
inline void add(int x,int y){
for(;x<=n;x+=x&-x)c[x]+=y;
}
inline int ask(int x){
int s=0;
for(;x;x-=x&-x)s+=c[x];
return s;
}
void solve(){
power(k);
rep(i,1,n)c[i]=0;
memset(f,0,sizeof(f));
f[7]=n*(n-1ll)/2%md*((md+1ll)/2)%md;
rep(i,1,n){
ll c1=ask(a[i]),c2=i-1-c1;
f[2]=(f[2]+(a[i]-1)*(n-a[i]-c2)+(a[i]-2)*(a[i]-1-c1))%md;
f[3]=(f[3]+(a[i]-2)*c1+(a[i]-1)*c2)%md;
f[4]=(f[4]+(n-a[i]-1)*(n-a[i]-c2)+(n-a[i])*(a[i]-1-c1))%md;
f[5]=(f[5]+(n-a[i])*c1+(n-a[i]-1)*c2)%md;
f[6]=(f[6]+c1)%md;
add(a[i],1);
}
ans=0;
ans=(ans+(cc-f[6])*s.a[1][1])%md;
ans=(ans+f[2]*n2%md*s.a[1][2])%md;
ans=(ans+f[3]*n2%md*s.a[1][3])%md;
ans=(ans+f[4]*n2%md*s.a[1][4])%md;
ans=(ans+f[5]*n2%md*s.a[1][5])%md;
ans=(ans+f[6]*s.a[1][6])%md;
ans=(ans+f[7]*s.a[1][7])%md;
cout<<(ans%md+md)%md<<'\n';
}
signed main(){
n=read(),k=read();
n2=pw(n-2,md-2),cc=n*(n-1ll)/2%md,ni=pw(cc,md-2);
rep(i,1,n)a[i]=read();
d.a[1][1]=(n-2ll)*(n-3)/2%md,d.a[1][2]=n-2,d.a[1][5]=n-2,d.a[1][6]=1;
d.a[2][1]=1,d.a[2][2]=((n-2ll)*(n-3)/2+n-3)%md,d.a[2][3]=1,d.a[2][4]=1,d.a[2][7]=n-3;
d.a[3][2]=1,d.a[3][3]=((n-2ll)*(n-3)/2+n-3)%md,d.a[3][5]=1,d.a[3][6]=1,d.a[3][7]=n-3;
d.a[4][2]=1,d.a[4][4]=((n-2ll)*(n-3)/2+n-3)%md,d.a[4][5]=1,d.a[4][6]=1,d.a[4][7]=n-3;
d.a[5][1]=1,d.a[5][5]=((n-2ll)*(n-3)/2+n-3)%md,d.a[5][3]=1,d.a[5][4]=1,d.a[5][7]=n-3;
d.a[6][1]=1,d.a[6][3]=n-2,d.a[6][4]=n-2,d.a[6][6]=(n-2ll)*(n-3)/2%md;
d.a[7][2]=d.a[7][3]=d.a[7][4]=d.a[7][5]=1,d.a[7][7]=n*(n-1ll)/2%md-4;
solve();
return 0;
}

浙公网安备 33010602011771号