結果
問題 | No.2327 Inversion Sum |
ユーザー |
![]() |
提出日時 | 2023-05-28 14:47:39 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 81 ms / 2,000 ms |
コード長 | 3,221 bytes |
コンパイル時間 | 1,951 ms |
コンパイル使用メモリ | 181,556 KB |
実行使用メモリ | 6,344 KB |
最終ジャッジ日時 | 2024-12-27 02:59:48 |
合計ジャッジ時間 | 3,727 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 30 |
ソースコード
#include <bits/stdc++.h>using namespace std;typedef long long int ll;typedef pair<ll,ll> P;typedef vector<ll> VI;typedef vector<VI> VVI;#define REP(i,n) for(int i=0;i<(n);i++)#define ALL(v) v.begin(),v.end()template<typename T> bool chmax(T& x, const T& y){return (x<y)?(x=y,true):false;};template<typename T> bool chmin(T& x, const T& y){return (x>y)?(x=y,true):false;};constexpr ll MOD=998244353;constexpr ll INF=2e18;template<typename X>struct Segtree{using F=function<X(X,X)>;int n; F f; X ex;vector<X> dat;Segtree(int n_, F f_, X ex_):f(f_), ex(ex_){n=1;while(n_>n){n*=2;}dat.assign(2*n,ex);}void set(int i, X x){dat[i+n-1]=x;}void build(){for(int k=n-2;k>=0;k--)dat[k]=f(dat[2*k+1],dat[2*k+2]);}void update(int i, X x){i+=n-1;dat[i]=x;while(i>0){i=(i-1)/2;dat[i]=f(dat[i*2+1],dat[i*2+2]);}}X query(int a, int b){return query_sub(a,b,0,0,n);}X query_sub(int a, int b, int k, int l, int r){if(r<=a||b<=l)return ex;else if(a<=l&&r<=b)return dat[k];else{X vl=query_sub(a,b,k*2+1,l,(l+r)/2);X vr=query_sub(a,b,k*2+2,(l+r)/2,r);return f(vl,vr);}}};long long power(long long x, long long y){x%=MOD;long long ret=1;while(y){if(y&1) ret=ret*x%MOD;x=x*x%MOD;y>>=1;}return ret;}long long divid(long long x, long long y){x%=MOD;return x*power(y,MOD-2)%MOD;}long long inv(int n){static vector<long long> a={1,1};if((int)a.size()<=n){for(int i=a.size();i<=n;i++)a.push_back(MOD-a[MOD%i]*(MOD/i)%MOD);}return a[n];}long long fact(int n){static vector<long long> a={1,1};if((int)a.size()<=n){for(int i=a.size();i<=n;i++)a.push_back(a.back()*i%MOD);}return a[n];}long long finv(int n){static vector<long long> a={1,1};if((int)a.size()<=n){for(int i=a.size();i<=n;i++)a.push_back(a.back()*inv(i)%MOD);}return a[n];}long long com(int n, int k){if(n<k||n<0||k<0) return 0;return fact(n)*finv(k)%MOD*finv(n-k)%MOD;}int main(){int n, m; cin >> n >> m;VI p(m), k(m);REP(i,m) cin >> p[i] >> k[i], p[i]--, k[i]--;ll ans=0;ans=(ans+divid(fact(n-m)*(n-m)%MOD*(n-m-1)%MOD,4))%MOD;VI x(n,-1);REP(i,m) x[k[i]]=p[i];Segtree<int> seg(n,[](int l, int r){return l+r;},0);REP(i,m) seg.set(p[i],1);seg.build();ll t=0;REP(i,n){if(x[i]!=-1){t+=seg.query(0,x[i]);seg.update(x[i],0);}}ans=(ans+t*fact(n-m)%MOD)%MOD;REP(i,m) seg.update(p[i],1);ll cnt=0;REP(i,n){if(x[i]!=-1){ll l=i-cnt;ll r=n-m-l;ll f=x[i]-seg.query(0,x[i]);ll g=n-x[i]-seg.query(x[i],n);ans=(ans+f*fact(n-m-1)%MOD*r%MOD)%MOD;ans=(ans+g*fact(n-m-1)%MOD*l%MOD)%MOD;cnt++;}}cout << ans << endl;return 0;}