結果
問題 | No.1300 Sum of Inversions |
ユーザー | hedwig100 |
提出日時 | 2020-11-27 22:47:31 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 342 ms / 2,000 ms |
コード長 | 5,507 bytes |
コンパイル時間 | 2,108 ms |
コンパイル使用メモリ | 190,180 KB |
実行使用メモリ | 39,216 KB |
最終ジャッジ日時 | 2024-07-26 19:07:15 |
合計ジャッジ時間 | 10,901 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 34 |
ソースコード
#include <bits/stdc++.h> using namespace std; #ifdef LOCAL_ void debug_out() {cerr << endl;} template<typename Head,typename... Tail> void debug_out(Head H,Tail... T){cerr << ' ' << H; debug_out(T...);} #define debug(...) cerr << 'L' << __LINE__ << " [" << #__VA_ARGS__ << "]:",debug_out(__VA_ARGS__) #define dump(x) cerr << 'L' << __LINE__ << " " << #x << " = " << (x) << endl; #else #define debug(...) (void(0)) #define dump(x) (void(0)) #endif #define rep(i,n) for (int i = 0; i < (int)(n); i ++) #define irep(i,n) for (int i = (int)(n) - 1;i >= 0;--i) using ll = long long; using PL = pair<ll,ll>; using P = pair<int,int>; constexpr int INF = 1000000000; constexpr long long HINF = 100000'00000'00000; constexpr long long MOD = 998244353; constexpr double EPS = 1e-4; constexpr double PI = 3.14159265358979; #pragma region Macros template<typename T1,typename T2> ostream &operator<<(ostream &os,const pair<T1,T2> &p) { os << '(' << p.first << ',' << p.second << ')'; return os; } template<typename T> ostream &operator<<(ostream &os,const vector<T> &v) { os << '['; for (auto &e:v) {os << e << ',';} os << ']'; return os; } // grid searh const int dy[8] = {-1,0,1,0,-1,-1,1,1}; const int dx[8] = {0,1,0,-1,-1,1,-1,1}; bool IN(int y,int x,int H,int W) {return (0 <= y)&&(y < H)&&(0 <= x)&&(x < W);} #pragma endregion template<class T> struct BinaryIndexedTree { int N,power = 1; vector<T> bit; BinaryIndexedTree(int N = 0): N(N){ bit.assign(N + 1,0); while (power <= N) power <<= 1; //power > N } void build(const vector<T> &A) { for (int i = 1;i <= N; ++i) add(i,A[i - 1]); } // add x to a[i] void add(int i,T x) { for (int idx = i; idx <= N; idx += (idx & -idx)) { bit[idx] += x; } } // return a[1] + a[2] + a[3] + .. + a[k] T sum(int k) { T ret = 0; for (int idx = k; idx > 0; idx -= (idx & -idx)) { ret += bit[idx]; } return ret; } // return a[l] + a[l + 1] + a[l + 2] + .. + a[r - 1] T sum(int l,int r) { return sum(r - 1) - sum(l - 1); } // return min index s.t. a[1] + a[2] + a[3] + .. + a[x] >= w int lower_bound(T w) { if (w <= 0) return 0; int x = 0; for (int r = power; r > 0; r >>= 1) { if (x + r <= N && bit[x + r] < w) { w -= bit[x + r]; x += r; } } return x + 1; } }; template<int Modulus> struct ModInt { long long x; ModInt(long long x = 0) :x((x%Modulus + Modulus)%Modulus) {} constexpr ModInt &operator+=(const ModInt a) {if ((x += a.x) >= Modulus) x -= Modulus; return *this;} constexpr ModInt &operator-=(const ModInt a) {if ((x += Modulus - a.x) >= Modulus) x -= Modulus; return *this;} constexpr ModInt &operator*=(const ModInt a) {(x *= a.x) %= Modulus; return *this;} constexpr ModInt &operator/=(const ModInt a) {return *this *= a.inverse();} constexpr ModInt operator+(const ModInt a) const {return ModInt(*this) += a.x;} constexpr ModInt operator-(const ModInt a) const {return ModInt(*this) -= a.x;} constexpr ModInt operator*(const ModInt a) const {return ModInt(*this) *= a.x;} constexpr ModInt operator/(const ModInt a) const {return ModInt(*this) /= a.x;} friend constexpr ostream& operator<<(ostream& os,const ModInt<Modulus>& a) {return os << a.x;} friend constexpr istream& operator>>(istream& is,ModInt<Modulus>& a) {return is >> a.x;} ModInt inverse() const {// x ^ (-1) long long a = x,b = Modulus,p = 1,q = 0; while (b) {long long d = a/b; a -= d*b; swap(a,b); p -= d*q; swap(p,q);} return ModInt(p); } ModInt pow(long long N) {// x ^ N ModInt a = 1; while (N) { if (N&1) a *= *this; *this *= *this; N >>= 1; } return a; } }; using mint = ModInt<998244353>; map<ll,int> compress(vector<ll> A) { sort(A.begin(),A.end()); A.erase(unique(A.begin(),A.end()),A.end()); map<ll,int> mp; rep(i,A.size()) mp[A[i]] = i; return mp; } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); int N; cin >> N; vector<ll> A(N); rep(i,N) cin >> A[i]; auto mp = compress(A); int M = mp.size(); vector<vector<int>> B(M); rep(i,N) { int idx = mp[A[i]]; B[idx].push_back(i); } vector<ll> cntL(N),cntR(N); vector<mint> left(N),right(N); mint tot = 0; int bf = 0; BinaryIndexedTree<mint> bit(N); BinaryIndexedTree<int> idx(N); rep(i,M) { for (int j:B[i]) { left[j] = tot - bit.sum(j+1); cntL[j] = bf - idx.sum(j+1); } for (int j:B[i]) { bit.add(j+1,mint(A[j])); idx.add(j+1,1); tot += A[j]; ++bf; } } BinaryIndexedTree<mint> bit2(N); BinaryIndexedTree<int> idx2(N); irep(i,M) { for (int j:B[i]) { right[j] = bit2.sum(j+1); cntR[j] = idx2.sum(j+1); } for (int j:B[i]) { bit2.add(j+1,mint(A[j])); idx2.add(j+1,1); } } mint ans = 0; rep(i,N) { ans += cntL[i]*cntR[i]%MOD*A[i]; if (cntL[i] > 0 && cntR[i] > 0) { ans += right[i]*cntL[i]; ans += left[i]*cntR[i]; } } cout << ans << '\n'; return 0; }