結果
問題 | No.1300 Sum of Inversions |
ユーザー | nesya |
提出日時 | 2020-11-27 22:45:28 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 482 ms / 2,000 ms |
コード長 | 12,589 bytes |
コンパイル時間 | 3,105 ms |
コンパイル使用メモリ | 242,048 KB |
実行使用メモリ | 23,060 KB |
最終ジャッジ日時 | 2024-07-26 19:05:05 |
合計ジャッジ時間 | 16,239 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 3 ms
9,932 KB |
testcase_01 | AC | 3 ms
9,816 KB |
testcase_02 | AC | 3 ms
9,804 KB |
testcase_03 | AC | 363 ms
21,628 KB |
testcase_04 | AC | 356 ms
22,364 KB |
testcase_05 | AC | 287 ms
16,704 KB |
testcase_06 | AC | 416 ms
22,824 KB |
testcase_07 | AC | 385 ms
23,004 KB |
testcase_08 | AC | 434 ms
22,608 KB |
testcase_09 | AC | 433 ms
22,516 KB |
testcase_10 | AC | 228 ms
16,336 KB |
testcase_11 | AC | 223 ms
16,236 KB |
testcase_12 | AC | 368 ms
22,576 KB |
testcase_13 | AC | 356 ms
21,812 KB |
testcase_14 | AC | 482 ms
22,848 KB |
testcase_15 | AC | 446 ms
22,524 KB |
testcase_16 | AC | 366 ms
22,504 KB |
testcase_17 | AC | 221 ms
16,136 KB |
testcase_18 | AC | 258 ms
16,596 KB |
testcase_19 | AC | 311 ms
22,484 KB |
testcase_20 | AC | 324 ms
22,472 KB |
testcase_21 | AC | 313 ms
21,304 KB |
testcase_22 | AC | 285 ms
16,864 KB |
testcase_23 | AC | 414 ms
22,040 KB |
testcase_24 | AC | 292 ms
17,092 KB |
testcase_25 | AC | 245 ms
16,504 KB |
testcase_26 | AC | 240 ms
16,340 KB |
testcase_27 | AC | 279 ms
16,748 KB |
testcase_28 | AC | 459 ms
22,636 KB |
testcase_29 | AC | 313 ms
21,316 KB |
testcase_30 | AC | 435 ms
22,556 KB |
testcase_31 | AC | 278 ms
17,104 KB |
testcase_32 | AC | 305 ms
16,944 KB |
testcase_33 | AC | 272 ms
22,872 KB |
testcase_34 | AC | 321 ms
22,968 KB |
testcase_35 | AC | 290 ms
23,048 KB |
testcase_36 | AC | 316 ms
23,060 KB |
ソースコード
#include<bits/stdc++.h> #define rep(i,m) for(long long i=0; i<m; i++) #define per(i,m) for(long long i=m-1; i>=0; i--) #define FOR(i,n,m) for(long long i=n; i<m; i++) #define ROF(i,n,m) for(long long i=m-1; i>=n; i--) #define SORT(v,n) do{sort(v,v+n);reverse(v,v+n);}while(0) #define all(x) (x).begin(),(x).end() #define F first #define S second #define MP make_pair #define MT make_tuple #define PB push_back #define PQ priority_queue #define EPS (1e-7) #define PI (acos(-1)) #define dump(x) cerr << #x << " = " << (x) << endl; #define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl; using namespace std; typedef long long ll; const ll INF = 1000000000000000000; const ll MOD = 998244353; typedef pair<int,int> P; typedef pair<ll,ll> LP; std::ostream &operator<<(std::ostream &dest, __int128_t value) { std::ostream::sentry s(dest); if (s) { __uint128_t tmp = value < 0 ? -value : value; char buffer[128]; char *d = std::end(buffer); do { --d; *d = "0123456789"[tmp % 10]; tmp /= 10; } while (tmp != 0); if (value < 0) { --d; *d = '-'; } int len = std::end(buffer) - d; if (dest.rdbuf()->sputn(d, len) != len) { dest.setstate(std::ios_base::badbit); } } return dest; } ll POW(ll x,ll n){ x%=MOD; if(n==0)return 1; if(n%2==0)return POW(x*x,n/2)%MOD; return x%MOD*POW(x,n-1)%MOD; } ll POW2(ll x,ll n){ if(n==0)return 1; if(n%2==0)return POW2(x*x,n/2); return x*POW2(x,n-1); } ll POW3(ll x,ll n,ll m){ x%=m; if(n==0)return 1; if(n%2==0)return POW3(x*x,n/2,m)%m; return x*POW3(x,n-1,m)%m; } ll gcd(ll u, ll v) { ll r; while (0 != v) { r = u % v; u = v; v = r; } return u; } ll lcm(ll u, ll v) { return u/gcd(u,v)*v; } ll kaikai[510000]={}; ll KAI(ll m) { if(kaikai[m])return kaikai[m]; if(m<0) return 0; if(m==0) return 1; kaikai[m]=m*KAI(m-1)%MOD; return kaikai[m]; } ll KAI2(ll m) { if(m<0) return 0; if(m==0) return 1; return m*KAI2(m-1); } ll extGCD(ll a, ll b, ll &x, ll &y) { if (b == 0) { x = 1; y = 0; return a; } ll d = extGCD(b, a%b, y, x); y -= a / b * x; return d; } inline ll mod(ll a, ll m) { return (a % m + m) % m; } ll modinv(ll a) { ll x, y; extGCD(a, MOD, x, y); return mod(x, MOD); } /* ll COM(ll m,ll n) { if(m<n) return 0; if(n<0) return 0; if(n==0) return 1; if(m==n) return 1; return m*modinv(n)%MOD*COM(m-1,n-1)%MOD; } */ ll COM(ll m,ll n) { if(m<n) return 0; if(n<0) return 0; if(n==0) return 1; if(m==n) return 1; return KAI(m)*modinv(KAI(n))%MOD*modinv(KAI(m-n))%MOD; } ll COM2(ll m,ll n) { if(m<n) return 0; if(n<0) return 0; if(n==0) return 1; if(m==n) return 1; return KAI2(m)/KAI2(n)/KAI2(m-n); } ll DEC(ll x,ll m,ll n)//xのm進数でのx^nの位の値 { if(m==2){ if(x&(1ll<<n))return 1; else return 0; } return x%POW2(m,n+1)/POW2(m,n); } ll keta(ll x,ll n)//xのn進数での桁数 { if(x==0)return 0; return keta(x/n,n)+1; } ll DIV(ll x,ll n)//x!のnで割り切れる回数 { if(x==0)return 0; return x/n+DIV(x/n,n); } ll ORD(ll x,ll n)//xのnで割り切れる回数 { if(x==0)return INF; if(x%n!=0)return 0; return 1+ORD(x/n,n); } ll SUP(ll x,ll n)//xのnで割れなくなるまで割ったときの余り { if(x==0)return 0; if(x%n!=0)return x; return SUP(x/n,n); } ll DigSum(ll n)//10進数での桁和 { if(n==0)return 0; return n%10+DigSum(n/10); } ll SGS(ll x,ll y, ll m)//1+x+…+x^(y-1)をmで割った余り { if(y==0)return 0; if(y%2==0){ return (1+POW3(x,y/2,m))*SGS(x,y/2,m)%m; } return (1+x*SGS(x,y-1,m))%m; } ll SSGS(ll x,ll y,ll m)//Σ[k=1→y](1+x+…+x^(k-1))をmで割った余り { if(y==0)return 0; if(y==1)return 1; if(y%2==0){ return (SSGS(x,y/2,m)*(POW3(x,y/2,m)+1)%m+SGS(x,y/2,m)*y/2%m)%m; } return (SSGS(x,y-1,m)*x%m+y)%m; } void shuffle(ll array[], ll size) { for(ll i = 0; i < size; i++) { ll j = rand()%size; ll t = array[i]; array[i] = array[j]; array[j] = t; } } ll SQRT(ll n){ ll ok,ng,mid; ng=n+1; if(303700500<ng)ng=303700500; ok=0; while(abs(ok-ng)>1){ mid=(ok+ng)/2; if(mid*mid<=n){ ok=mid; } else{ ng=mid; } } return ok; } struct UnionFind { vector<int> par; vector<int> sizes; UnionFind(int n) : par(n), sizes(n, 1) { rep(i,n) par[i] = i; } int find(int x) { if (x == par[x]) return x; return par[x] = find(par[x]); } void unite(int x, int y) { x = find(x); y = find(y); if (x == y) return; if (sizes[x] < sizes[y]) swap(x, y); par[y] = x; sizes[x] += sizes[y]; } bool same(int x, int y) { return find(x) == find(y); } int size(int x) { return sizes[find(x)]; } }; map< int64_t, int > prime_factor(int64_t n) { map< int64_t, int > ret; for(int64_t i = 2; i * i <= n; i++) { while(n % i == 0) { ret[i]++; n /= i; } } if(n != 1) ret[n] = 1; return ret; } bool is_prime(int64_t x) { if(x==1)return false; for(int64_t i = 2; i * i <= x; i++) { if(x % i == 0) return false; } return true; } struct edge{ll to, cost;}; struct Dij{ ll V; vector<vector<edge> > G; vector<ll> d; Dij(ll n){ init(n); } void init(ll n){ V = n; G.resize(V); d.resize(V); rep(i,V){ d[i] = INF; } } void add(ll s, ll t, ll cost){ edge e; e.to = t, e.cost = cost; G[s].push_back(e); } void find(ll s){ rep(i,V){ d[i] = INF; } d[s] = 0; priority_queue<LP,vector<LP>, greater<LP> > que; que.push(LP(0,s)); while(!que.empty()){ LP p = que.top(); que.pop(); ll v = p.second; if(d[v]<p.first) continue; for(auto e : G[v]){ if(d[e.to]>d[v]+e.cost){ d[e.to] = d[v]+e.cost; que.push(LP(d[e.to],e.to)); } } } } }; struct BF{ ll V; vector<vector<edge>> G; vector<ll> d; BF(ll n){ init(n); } void init(ll n){ V = n; G.resize(V); d.resize(V); rep(i,V){ d[i]=INF; } } void add(ll s, ll t, ll cost){ edge e; e.to=t,e.cost=cost; G[s].push_back(e); } bool find(ll s){ rep(i,V){ d[i]=INF; } d[s]=0; rep(i,V){ rep(j,V){ ll m=G[j].size(); rep(k,m){ edge e=G[j][k]; if(d[j]!=INF&&d[e.to]>d[j]+e.cost){ d[e.to]=d[j]+e.cost; if(i==V-1)return true; } } } } return false; } bool find2(ll s,ll t){ rep(i,V){ d[i]=INF; } d[s]=0; rep(i,V*2){ rep(j,V){ ll m=G[j].size(); rep(k,m){ edge e=G[j][k]; if(d[j]!=INF&&d[e.to]>d[j]+e.cost){ if(i>=V-1&&e.to==t)return true; else if(i>=V-1)d[e.to]=-INF; else d[e.to]=d[j]+e.cost; } } } } return false; } }; ll dist[400][400]; void WF(ll n){ rep(i,n)rep(j,n)rep(k,n)dist[j][k]=min(dist[j][k],dist[j][i]+dist[i][k]); } struct bit{ ll m; vector<ll> b; bit(ll i){ m=i; b.resize(m+1); } ll num(ll i){ return b[i]; } ll sum(ll i){ ll s=0; while(i>0){ s+=b[i]; i-=i&-i; } return s; } void add(ll i, ll x){ while(i<=m){ b[i]+=x; i+=i&-i; } } }; struct Segtree{ ll N=1; ll elem; vector<ll> value; ll calc(ll s,ll t){ return (s+t)%MOD; //演算 } Segtree(ll n,ll Elem){ elem=Elem; while(N<n)N*=2; value.assign(2*N-1,elem); } void update(ll i,ll x) { i+=N-1; value[i]=x; while(i>0){ i=(i-1)/2; value[i]=calc(value[i*2+1],value[i*2+2]); } } ll query(ll a,ll b,ll k,ll l,ll r){ if(r<=a||b<=l)return elem; if(a<=l&&r<=b)return value[k]; else{ ll c1=query(a,b,2*k+1,l,(l+r)/2); ll c2=query(a,b,2*k+2,(l+r)/2,r); return calc(c1,c2); } } ll find(ll s,ll t){ return query(s,t+1,0,0,N); } ll v(ll s){ return query(s,s+1,0,0,N); } }; string LCS(string s,string t){ ll x=s.size(); ll dp[x+1][x+1]={},m[x+1][x+1]={},a,b; string h; stack<char>p; a=s.size(); b=t.size(); rep(i,a){ rep(j,b){ if(s[i]==t[j]){ dp[i+1][j+1]=dp[i][j]+1; m[i+1][j+1]=0; } dp[i+1][j+1]=max({dp[i+1][j],dp[i][j+1],dp[i+1][j+1]}); if(dp[i+1][j+1]==dp[i+1][j]){ m[i+1][j+1]=1; } if(dp[i+1][j+1]==dp[i][j+1]){ m[i+1][j+1]=2; } } } while(a>=1&&b>=1){ if(m[a][b]==0){ p.push(s[a-1]); a--; b--; } else if(m[a][b]==1)b--; else a--; } while(p.size()){ h+=p.top(); p.pop(); } return h; } struct Edge{ ll src, dst; ll cap; Edge(ll src_, ll dst_, ll cap_) : src(src_), dst(dst_), cap(cap_) { } }; struct EK{ ll n; vector<ll> prev, dist; vector<vector<ll>> cap, flow; vector<vector<ll>> g; ll inf; EK(ll n) : n(n), cap(n, vector<ll>(n)), flow(n, vector<ll>(n)), g(n, vector<ll>()), inf(INF){} EK(const vector<vector<Edge>> &graph){ *this = EK(graph.size()); rep(i,n) for(auto &e : graph[i]) add(e.src, e.dst, e.cap); } void add(ll u, ll v, ll c){ cap[u][v] += c; cap[v][u] += c; flow[v][u] += c; g[u].push_back(v); g[v].push_back(u); } ll find(ll s, ll t){ ll res = 0, aug = 1; while(aug > 0){ prev.assign(n, -1); dist.assign(n, inf); dist[s] = 0; res += (aug = augment(s,t)); } return res; } ll augment(ll s, ll t){ queue<pair<ll,ll>> q; q.emplace(s,inf); ll aug = 0; while(q.size()){ ll v; ll f; tie(v,f) = q.front(); q.pop(); if(v == t){ aug = f; break; } for(const ll& d : g[v]){ if(dist[d] <= dist[v] + 1 || cap[v][d] - flow[v][d] == 0) continue; dist[d] = dist[v] + 1; prev[d] = v; q.emplace(d, min(f, cap[v][d] - flow[v][d])); } } if(aug == 0) return 0; ll c = t; while(c != s){ ll p = prev[c]; flow[p][c] += aug; flow[c][p] -= aug; c = p; } return aug; } }; ll LIS(vector<ll>a) { ll n=a.size(); ll dp[n]; fill(dp,dp+n,INF); rep(i,n)*lower_bound(dp,dp+n,a[i])=a[i]; return lower_bound(dp,dp+n,INF)-dp; } struct RMQ{ ll N=1; ll elem=INF; vector<LP> value; RMQ(ll n){ while(N<n)N*=2; rep(i,2*N-1)value.PB(MP(elem,INF)); } void update(ll i,ll x) { i+=N-1; value[i]=MP(x,i+1-N); } void UPDATE(){ per(i,N-1)value[i]=min(value[i*2+1],value[i*2+2]); } LP query(ll a,ll b,ll k,ll l,ll r){ if(r<=a||b<=l)return MP(INF,INF); if(a<=l&&r<=b)return value[k]; return min(query(a,b,2*k+1,l,(l+r)/2),query(a,b,2*k+2,(l+r)/2,r)); } ll find(ll s,ll t){ return query(s,t+1,0,0,N).S; } }; struct LCA{ vector<vector<ll>>v; vector<ll>vs; vector<ll>id; vector<ll>depth; vector<RMQ>r; ll k; ll N; LCA(ll n){ v.resize(n); id.resize(n); r.PB((RMQ){2*n-1}); N=n; } void add(ll s,ll t){ v[s].PB(t); } void root(ll n){ k=0; dfs(n,0); r[0].UPDATE(); } void dfs(ll n,ll d){ id[n]=k; ll m=v[n].size(); rep(i,m){ vs.PB(n); depth.PB(d); r[0].update(k,d); k++; dfs(v[n][i],d+1); } vs.PB(n); depth.PB(d); r[0].update(k,d); k++; } ll find(ll s,ll t){ return vs[r[0].find(min(id[s],id[t]),max(id[s],id[t]))]; } ll dist(ll s,ll t){ return depth[id[s]]+depth[id[t]]-2*depth[r[0].find(min(id[s],id[t]),max(id[s],id[t]))]; } }; int main(){ ll n,a[210000],ans=0,x[210000],y[210000],z[210000],w[210000]; cin >> n; rep(i,n)cin >> a[i]; vector<LP>v; rep(i,n)v.PB(MP(a[i],i)); sort(all(v)); Segtree s(n,0); Segtree s2(n,0); rep(i,n){ s.update(v[i].S,v[i].F); s2.update(v[i].S,1); x[v[i].S]=s2.find(v[i].S+1,n-1); y[v[i].S]=s.find(v[i].S+1,n-1); } reverse(all(v)); rep(i,n)s.update(i,0); rep(i,n)s2.update(i,0); rep(i,n){ s.update(v[i].S,v[i].F); s2.update(v[i].S,1); z[v[i].S]=s2.find(0,v[i].S-1); w[v[i].S]=s.find(0,v[i].S-1); } rep(i,n){ ans+=x[i]*z[i]%MOD*a[i]%MOD; ans%=MOD; ans+=y[i]*z[i]%MOD; ans%=MOD; ans+=x[i]*w[i]%MOD; ans%=MOD; } printf("%lld",mod(ans,MOD)); }