結果
| 問題 |
No.1300 Sum of Inversions
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-11-28 04:04:54 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 370 ms / 2,000 ms |
| コード長 | 3,473 bytes |
| コンパイル時間 | 1,216 ms |
| コンパイル使用メモリ | 93,096 KB |
| 実行使用メモリ | 22,812 KB |
| 最終ジャッジ日時 | 2024-09-12 21:57:55 |
| 合計ジャッジ時間 | 10,887 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 34 |
ソースコード
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <map>
#include <stack>
using namespace std;
const int MOD = 998244353;
struct segK{//非再帰
int n;
long long MIN;
int size;
vector<long long> dat;
segK(int n_){
n = 1;
MIN = 0;
size = n_;
while(n < n_) n *= 2;
dat.resize(2 * n);
for(int i = 1; i < 2 * n; i++) dat[i] = MIN;
}
void update(int k, long long a){
k += n;
dat[k] += a;
while(k > 0){
k >>= 1;
dat[k] = (dat[k << 1 | 0] + dat[k << 1 | 1]) % MOD;
}
}
long long query(int l, int r){
long long res = 0;
l += n;
r += n;
while(r > l){
if(l & 1) res = res + dat[l++];
if(r & 1) res = res + dat[--r];
l >>= 1;
r >>= 1;
}
return res % MOD;
}
int right_bin(int l, long long v) {//l番目の値vより小さくて、l以下で最も大きいインデックスを返す
if(l == size) return l;
l += n;
do {
while (l % 2 == 0) l >>= 1;
if (dat[l] >= v) {
while (l < n) {
l = (2 * l);
if (dat[l] < v) {
l++;
}
}
return l - n;
}
l++;
} while ((l & -l) != l);
return size;
}
int left_bin(int r, long long v) {
if(r == 0) return r;
r += n;
do {
r--;
while (r > 1 && (r % 2)) r >>= 1;
if (dat[r] <= v) {
while (r < n) {
r = (2 * r + 1);
if (dat[r] > v) {
r--;
}
}
return r + 1 - n;
}
} while ((r & -r) != r);
return 0;
}
};
template<class T>
vector<T> press(vector<T> &a){
vector<T> temp = a;
sort(temp.begin(), temp.end());
temp.erase(unique(temp.begin(), temp.end()), temp.end());
for(int i = 0; i < a.size(); i++){
a[i] = lower_bound(temp.begin(), temp.end(), a[i]) - temp.begin();
}
return temp;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
vector<long long> a(N);
for(int i = 0; i < N; i++) cin >> a[i];
vector<long long> za = press(a);
int m = za.size();
segK seg1(m), seg2(m), seg3(m), seg4(m);
for(int i = 0; i < N; i++){
seg3.update(a[i], za[a[i]]);
seg4.update(a[i], 1);
}
long long ans = 0;
for(int i = 0; i < N; i++){
if(i == 0 || i == N - 1){
seg1.update(a[i], za[a[i]]);
seg2.update(a[i], 1);
seg3.update(a[i], -za[a[i]]);
seg4.update(a[i], -1);
}
else{
seg1.update(a[i], za[a[i]]);
seg2.update(a[i], 1);
seg3.update(a[i], -za[a[i]]);
seg4.update(a[i], -1);
long long s = seg1.query(a[i] + 1, m), s1 = seg2.query(a[i] + 1, m);
long long t = seg3.query(0, a[i]), t1 = seg4.query(0, a[i]);
//cout << s << ' ' << t << endl;
if(t1 != 0 && s1 != 0){
ans += s * t1 % MOD + t * s1 % MOD + za[a[i]] * t1 % MOD * s1 % MOD;
ans %= MOD;
}
}
}
cout << ans << endl;
}