题意:给你一个序列s,你把这个序列的所有不同排列按字典序排列后,求s的排名mod m
不保证 $m$ 是质数。
题解:我们记 $cnt_i$ 表示填到当前 $i$ 这个数还有多少个,不难发现题目要求的是:
$$\sum_{i=1}^n \frac{(n-i)!}{\Pi_j cnt_j} (\sum_{j < s_i}cnt_j)$$
显然后面的和式可以用树状数组轻松维护。
发现 $m$ 不一定是个质数,我们质因数分解后对于每一个 $p_i^{e_i}$ 分开做就好了。中间要将所有的数的 $p_i$ 因子都提取出来。(感觉和礼物那个题差不多)
最后 CRT 合并即可。
/*
* Author: RainAir
* Time: 2019-08-18 19:01:38
*/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define fi first
#define se second
#define U unsigned
#define Re register
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(Re int i = a;i <= b;++i)
#define ROF(i,a,b) for(Re int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl
#define int LL
const int MAXN = 300000+5;
int s[MAXN],fac[MAXN],b[MAXN],pw[MAXN],cnt[MAXN];
int ls[MAXN],ln,n,m,ans[MAXN];
std::vector<std::pair<int,int> > dec;
struct BIT{
int tree[MAXN];
#define lowbit(x) ((x)&(-x))
inline void clear(){
CLR(tree,0);
}
inline void add(int pos,int x){
while(pos <= n){
tree[pos] += x;
pos += lowbit(pos);
}
}
inline int query(int pos){
int res = 0;
while(pos){
res += tree[pos];
pos -= lowbit(pos);
}
return res;
}
}bit;
inline int qpow(int a,int n){
int res = 1;
while(n){
if(n & 1) res = res*a;
a = a*a;n >>= 1;
}
return res;
}
inline void fg(int x){
int q = std::sqrt(1.0*x);
FOR(i,2,q){
if(!(x%i)){
int cnt = 0;
while(!(x%i)) x /= i,cnt++;
dec.pb(MP(i,cnt));
}
}
if(x != 1) dec.pb(MP(x,1));
}
inline void exgcd(int a,int b,int &x,int &y){
if(!b){
x = 1;y = 0;
return;
}
exgcd(b,a%b,x,y);
int t = x;x = y;y = t-(a/b)*y;
}
inline int inv(int a,int b){ // ax==1 (mod b)
int x,y;exgcd(a,b,x,y);
return (x+b)%b;
}
inline int solve(int p,int e){
int P = qpow(p,e);bit.clear();
fac[0] = 1;pw[0] = 1;b[0] = 0;
FOR(i,1,n){
int tot = 0,t = i;
while(!(t%p)) t /= p,tot++;
fac[i] = fac[i-1]*t%P;
b[i] = b[i-1]+tot;
pw[i] = pw[i-1]*p%P;
bit.add(s[i],1);cnt[s[i]]++;
}
// FOR(i,1,n) DEBUG(cnt[i]);
int ans = 0,invb = 0,inv = 1;
FOR(i,1,ln) inv = 1llinv::inv(fac[cnt[i]],P)%P,invb += b[cnt[i]];
FOR(i,1,n){
(ans += bit.query(s[i]-1)fac[n-i]%Pinv%P*pw[b[n-i]-invb]%P) %= P;
inv = 1llinvfac[cnt[s[i]]]%P*::inv(fac[cnt[s[i]]-1],P)%P;
invb -= b[cnt[s[i]]];invb += b[--cnt[s[i]]];
bit.add(s[i],-1);
}
// FOR(i,1,n) assert(!cnt[i]);
ans++;ans %= P;
return ans;
}
signed main(){
scanf("%lld%lld",&n,&m);
FOR(i,1,n) scanf("%lld",s+i),ls[i] = s[i];
std::sort(ls+1,ls+n+1);
ln = std::unique(ls+1,ls+n+1)-ls-1;//DEBUG(ln);
FOR(i,1,n) s[i] = std::lower_bound(ls+1,ls+ln+1,s[i])-ls;
fg(m);
int sz = dec.size(),res = 0;
FOR(i,1,sz) ans[i] = solve(dec[i-1].fi,dec[i-1].se);
FOR(i,1,sz){
int P = qpow(dec[i-1].fi,dec[i-1].se);
int inv = ::inv(m/P,P);
(res += m/Pinv%mans[i]%m) %= m;
}
printf("%lldn",(res+m)%m);
return 0;
}