传送门:https://www.luogu.org/problem/P5367
刚开始背的式子,一测WAWAWA......(式子背错了.....
然后请教了下大佬。
就考虑比当前排列字典序小的有哪些。
第i个位置,后边剩下n-i个位置没有填,所以(n-i)!
考虑第i个位置,就再乘以( i-ask(a[i]) ) ask(a[i])为再i位置之前出现的比a[i]小的数的个数。(用树状数组维护
#include<cstdio> #define R register typedef long long ll; using namespace std; const int mod=998244353; int n,a[1001000],c[1001000]; inline void add(int x){ for(;x<=n;x+=x&-x) c[x]++; } inline int ask(int x){ int to=0; for(;x;x-=x&-x) to+=c[x]; return to; } ll rev[1001000],ans; inline int abc(int x){ if(x<0) return ~x+1; return x; } int main (){ scanf("%d",&n); rev[0]=1; for(R int i=1;i<=n;i++){ scanf("%d",&a[i]); rev[i]=(rev[i-1]*i)%mod; } for(R int i=1;i<=n;i++){ add(a[i]); ans=(ans+1ll*(a[i]-ask(a[i]))*rev[n-i])%mod; } printf("%lld ",(ans+1)%mod); return 0; }