結果
問題 | No.1300 Sum of Inversions |
ユーザー | Chanyuh |
提出日時 | 2020-12-31 17:01:48 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 291 ms / 2,000 ms |
コード長 | 7,685 bytes |
コンパイル時間 | 1,710 ms |
コンパイル使用メモリ | 138,164 KB |
実行使用メモリ | 22,752 KB |
最終ジャッジ日時 | 2024-10-09 16:19:23 |
合計ジャッジ時間 | 11,522 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,816 KB |
testcase_01 | AC | 2 ms
6,816 KB |
testcase_02 | AC | 2 ms
6,816 KB |
testcase_03 | AC | 222 ms
22,000 KB |
testcase_04 | AC | 217 ms
22,008 KB |
testcase_05 | AC | 179 ms
13,360 KB |
testcase_06 | AC | 250 ms
22,324 KB |
testcase_07 | AC | 236 ms
22,256 KB |
testcase_08 | AC | 277 ms
22,412 KB |
testcase_09 | AC | 263 ms
22,480 KB |
testcase_10 | AC | 150 ms
13,076 KB |
testcase_11 | AC | 152 ms
13,140 KB |
testcase_12 | AC | 213 ms
21,832 KB |
testcase_13 | AC | 203 ms
21,948 KB |
testcase_14 | AC | 291 ms
22,724 KB |
testcase_15 | AC | 257 ms
22,416 KB |
testcase_16 | AC | 227 ms
22,168 KB |
testcase_17 | AC | 133 ms
12,920 KB |
testcase_18 | AC | 160 ms
13,288 KB |
testcase_19 | AC | 182 ms
21,688 KB |
testcase_20 | AC | 197 ms
21,612 KB |
testcase_21 | AC | 200 ms
21,724 KB |
testcase_22 | AC | 185 ms
13,364 KB |
testcase_23 | AC | 256 ms
22,208 KB |
testcase_24 | AC | 191 ms
13,396 KB |
testcase_25 | AC | 155 ms
13,004 KB |
testcase_26 | AC | 155 ms
13,112 KB |
testcase_27 | AC | 170 ms
13,340 KB |
testcase_28 | AC | 277 ms
22,500 KB |
testcase_29 | AC | 189 ms
21,760 KB |
testcase_30 | AC | 270 ms
22,276 KB |
testcase_31 | AC | 182 ms
13,372 KB |
testcase_32 | AC | 183 ms
13,536 KB |
testcase_33 | AC | 20 ms
6,816 KB |
testcase_34 | AC | 35 ms
6,820 KB |
testcase_35 | AC | 153 ms
22,636 KB |
testcase_36 | AC | 159 ms
22,752 KB |
ソースコード
#include<iostream> #include<array> #include<string> #include<cstdio> #include<vector> #include<cmath> #include<algorithm> #include<functional> #include<iomanip> #include<queue> #include<ciso646> #include<random> #include<map> #include<set> #include<complex> #include<bitset> #include<stack> #include<unordered_map> #include<utility> #include<tuple> #include<cassert> using namespace std; typedef long long ll; typedef unsigned int ui; const ll mod = 998244353; const ll INF = (ll)1000000007 * 1000000007; typedef pair<int, int> P; #define stop char nyaa;cin>>nyaa; #define rep(i,n) for(int i=0;i<n;i++) #define per(i,n) for(int i=n-1;i>=0;i--) #define Rep(i,sta,n) for(int i=sta;i<n;i++) #define Per(i,sta,n) for(int i=n-1;i>=sta;i--) #define rep1(i,n) for(int i=1;i<=n;i++) #define per1(i,n) for(int i=n;i>=1;i--) #define Rep1(i,sta,n) for(int i=sta;i<=n;i++) typedef long double ld; const ld eps = 1e-8; const ld pi = acos(-1.0); typedef pair<ll, ll> LP; int dx[4]={1,-1,0,0}; int dy[4]={0,0,1,-1}; template<class T>bool chmax(T &a, const T &b) {if(a<b){a=b;return 1;}return 0;} template<class T>bool chmin(T &a, const T &b) {if(b<a){a=b;return 1;}return 0;} template <class S, S (*op)(S, S), S (*e)()> struct SegmentTree { public: SegmentTree() : SegmentTree(0) {} SegmentTree(int n) : SegmentTree(std::vector<S>(n, e())) {} SegmentTree(const std::vector<S>& v) : _n(int(v.size())) { log = ceil_pow2(_n); size = 1 << log; d = std::vector<S>(2 * size, e()); for (int i = 0; i < _n; i++) d[size + i] = v[i]; for (int i = size - 1; i >= 1; i--) { update(i); } } void set_val(int p, S x) { assert(0 <= p && p < _n); p += size; d[p] = x; for (int i = 1; i <= log; i++) update(p >> i); } S get(int p) { assert(0 <= p && p < _n); return d[p + size]; } S query(int l, int r) { assert(0 <= l && l <= r && r <= _n); S sml = e(), smr = e(); l += size; r += size; while (l < r) { if (l & 1) sml = op(sml, d[l++]); if (r & 1) smr = op(d[--r], smr); l >>= 1; r >>= 1; } return op(sml, smr); } S all_query() { return d[1]; } template <bool (*f)(S)> int max_right(int l) {//f(op([l,r)))==trueを満たす最大のr return max_right(l, [](S x) { return f(x); }); } template <class F> int max_right(int l, F f) { assert(0 <= l && l <= _n); assert(f(e())); if (l == _n) return _n; l += size; S sm = e(); do { while (l % 2 == 0) l >>= 1; if (!f(op(sm, d[l]))) { while (l < size) { l = (2 * l); if (f(op(sm, d[l]))) { sm = op(sm, d[l]); l++; } } return l - size; } sm = op(sm, d[l]); l++; } while ((l & -l) != l); return _n; } template <bool (*f)(S)> int min_left(int r) {//f(op([l,r)))==trueを満たす最小のl return min_left(r, [](S x) { return f(x); }); } template <class F> int min_left(int r, F f) { assert(0 <= r && r <= _n); assert(f(e())); if (r == 0) return 0; r += size; S sm = e(); do { r--; while (r > 1 && (r % 2)) r >>= 1; if (!f(op(d[r], sm))) { while (r < size) { r = (2 * r + 1); if (f(op(d[r], sm))) { sm = op(d[r], sm); r--; } } return r + 1 - size; } sm = op(d[r], sm); } while ((r & -r) != r); return 0; } private: int _n, size, log; std::vector<S> d; void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); } int ceil_pow2(int n) { int x = 0; while ((1U << x) < (unsigned int)(n)) x++; return x; } }; template<int mod> struct ModInt { long long x; static constexpr int MOD = mod; ModInt() : x(0) {} ModInt(long long y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {} explicit operator int() const {return x;} ModInt &operator+=(const ModInt &p) { if((x += p.x) >= mod) x -= mod; return *this; } ModInt &operator-=(const ModInt &p) { if((x += mod - p.x) >= mod) x -= mod; return *this; } ModInt &operator*=(const ModInt &p) { x = (int)(1LL * x * p.x % mod); return *this; } ModInt &operator/=(const ModInt &p) { *this *= p.inverse(); return *this; } ModInt operator-() const { return ModInt(-x); } ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; } ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; } ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; } ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; } ModInt operator%(const ModInt &p) const { return ModInt(0); } bool operator==(const ModInt &p) const { return x == p.x; } bool operator!=(const ModInt &p) const { return x != p.x; } ModInt inverse() const{ int a = x, b = mod, u = 1, v = 0, t; while(b > 0) { t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v); } return ModInt(u); } ModInt power(long long n) const { ModInt ret(1), mul(x); while(n > 0) { if(n & 1) ret *= mul; mul *= mul; n >>= 1; } return ret; } ModInt power(const ModInt p) const{ return ((ModInt)x).power(p.x); } friend ostream &operator<<(ostream &os, const ModInt<mod> &p) { return os << p.x; } friend istream &operator>>(istream &is, ModInt<mod> &a) { long long x; is >> x; a = ModInt<mod>(x); return (is); } }; using modint = ModInt<mod>; template<typename T> struct Compress{ vector<T> V; Compress(){ V.clear(); } Compress(vector<T> &V):V(V){} void add(T x){ V.push_back(x); } int build(){ sort(V.begin(),V.end()); V.erase(unique(V.begin(),V.end()),V.end()); return V.size(); } int get(T x){//get the index of the minimum element which is greater than x return lower_bound(V.begin(),V.end(),x)-V.begin(); } pair<int, int> section(T l,T r){//get the range of indexes of [l,r) int l_=get(l),r_=get(r); return pair<int,int>(l_,r_); } T &operator [] (int i) {return V[i];}; }; int n; int a[200010]; modint f(modint a,modint b){return a+b;} modint e(){return 0;} void solve(){ cin >> n; Compress<int> comp; rep(i,n){ cin >> a[i]; comp.add(a[i]); } int m=comp.build(); rep(i,n) a[i]=comp.get(a[i]); SegmentTree<modint,f,e> seg1_sum(m),seg1_num(m),seg2_sum(m),seg2_num(m); modint ans=0; per(i,n){ ans+=seg2_sum.query(0,a[i])+seg2_num.query(0,a[i])*(modint)comp[a[i]]; seg2_sum.set_val(a[i],seg2_sum.get(a[i])+seg1_sum.query(0,a[i])+seg1_num.query(0,a[i])*(modint)comp[a[i]]); seg2_num.set_val(a[i],seg2_num.get(a[i])+seg1_num.query(0,a[i])); seg1_sum.set_val(a[i],seg1_sum.get(a[i])+(modint)comp[a[i]]); seg1_num.set_val(a[i],seg1_num.get(a[i])+1); } cout << ans << endl; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout << fixed << setprecision(50); solve(); }