[hdu7200]Yet Another Easy Permutation Count Problem
令$x_{i}=\sum_{j=1}^{i-1}[P_{i}<P_{j}]$,则$x_{i}\in [0,i)$与$\{P_{i}\}$构成双射
在此基础上,每轮冒泡排序即将所有$x_{i}>0$的位置均减$1$并左移$1$位
$i$为好位置$\iff x_{i}=0<x_{i+1}$,结合前者每个$i$的贡献为$\max(x_{i+1}-x_{i},0)$
显然$x_{i}<x_{i+1}\iff P_{i}>P_{i+1}$,并代入$x_{i}$的式子,贡献也即$\sum_{j=1}^{i}[P_{j}\in (P_{i+1},P_{i}]]$
将贡献式拆开,对三个变量是否确定分类讨论,并特判$i=j$的情况即可
可以用树状数组维护,时间复杂度为$o(n\log n)$,可以通过
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 1000005 4 #define mod 998244353 5 #define ll long long 6 #define lowbit(k) (k&(-k)) 7 int t,n,m,x,y,cnt,Cnt,ans,fac[N],a[N],sum[N]; 8 int C(int n){ 9 return (ll)n*(n-1)/2%mod; 10 } 11 int C3(int n){ 12 return (ll)n*(n-1)%mod*(n-2)%mod*(mod+1)/6%mod; 13 } 14 struct TA{ 15 int f[N]; 16 void clear(){ 17 for(int i=1;i<=n;i++)f[i]=0; 18 } 19 void update(int k,int x){ 20 while (k<=n)f[k]=(f[k]+x)%mod,k+=lowbit(k); 21 } 22 int query(int k){ 23 int ans=0; 24 while (k)ans=(ans+f[k])%mod,k^=lowbit(k); 25 return ans; 26 } 27 int query(int l,int r){ 28 return (query(r)-query(l)+mod)%mod; 29 } 30 }f1,f2,f3; 31 int main(){ 32 fac[0]=1; 33 for(int i=1;i<N;i++)fac[i]=(ll)fac[i-1]*i%mod; 34 scanf("%d",&t); 35 while (t--){ 36 scanf("%d%d",&n,&m); 37 for(int i=1;i<=n;i++)a[i]=sum[i]=0; 38 for(int i=1;i<=m;i++){ 39 scanf("%d%d",&x,&y); 40 a[x]=y,sum[y]=1; 41 } 42 for(int i=1;i<=n;i++)sum[i]=(sum[i]^1)+sum[i-1]; 43 m=sum[n],cnt=Cnt=ans=0,f1.clear(),f2.clear(),f3.clear(); 44 for(int i=1;i<n;i++){ 45 if ((a[i])&&(a[i+1])){ 46 if (a[i]>a[i+1]){ 47 ans=(ans+(ll)fac[m]*(1+f1.query(a[i+1],a[i])))%mod; 48 if (cnt)ans=(ans+(ll)cnt*fac[m-1]%mod*(sum[a[i]]-sum[a[i+1]]))%mod; 49 } 50 } 51 if ((a[i])&&(!a[i+1])){ 52 ans=(ans+(ll)fac[m-1]*(sum[a[i]]+f2.query(a[i])))%mod; 53 if (cnt)ans=(ans+(ll)cnt*fac[m-2]%mod*C(sum[a[i]]))%mod; 54 } 55 if ((!a[i])&&(a[i+1])){ 56 ans=(ans+(ll)fac[m-1]*((m-sum[a[i+1]])+f3.query(a[i+1],n)))%mod; 57 if (cnt)ans=(ans+(ll)cnt*fac[m-2]%mod*C(m-sum[a[i+1]]))%mod; 58 } 59 if ((!a[i])&&(!a[i+1])){ 60 ans=(ans+(ll)fac[m-2]*(C(m)+Cnt))%mod; 61 if (cnt)ans=(ans+(ll)cnt*fac[m-3]%mod*C3(m))%mod; 62 } 63 if (!a[i])cnt++; 64 else{ 65 Cnt=(Cnt+(ll)sum[a[i]]*(m-sum[a[i]]))%mod; 66 f1.update(a[i],1),f2.update(a[i],sum[a[i]]),f3.update(a[i],m-sum[a[i]]); 67 } 68 } 69 printf("%d\n",ans); 70 } 71 return 0; 72 }