結果
| 問題 | No.404 部分門松列 |
| コンテスト | |
| ユーザー |
kwm_t
|
| 提出日時 | 2026-06-08 20:51:13 |
| 言語 | C++23 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 155 ms / 2,000 ms |
| コード長 | 3,028 bytes |
| 記録 | |
| コンパイル時間 | 4,450 ms |
| コンパイル使用メモリ | 380,764 KB |
| 実行使用メモリ | 15,232 KB |
| 最終ジャッジ日時 | 2026-06-08 20:51:26 |
| 合計ジャッジ時間 | 12,208 ms |
|
ジャッジサーバーID (参考情報) |
judge1_0 / judge3_0 |
| 純コード判定待ち |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 31 |
ソースコード
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
// using mint = modint1000000007;
// const int mod = 1000000007;
// using mint = modint998244353;
// const int mod = 998244353;
// const int INF = 1e9;
// const long long LINF = 1e18;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep2(i, l, r) for (int i = (l); i < (r); ++i)
#define rrep(i, n) for (int i = (n)-1; i >= 0; --i)
#define rrep2(i, l, r) for (int i = (r)-1; i >= (l); --i)
#define all(x) (x).begin(), (x).end()
#define allR(x) (x).rbegin(), (x).rend()
#define P pair<int, int>
template<typename A, typename B> inline bool chmax(A &a, const B &b) { if (a < b) { a = b; return true; } return false; }
template<typename A, typename B> inline bool chmin(A &a, const B &b) { if (a > b) { a = b; return true; } return false; }
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
// 実装はchat gpt
int N;
cin >> N;
vector<long long> A(N);
for (int i = 0; i < N; i++) cin >> A[i];
// 座圧
vector<long long> xs = A;
sort(xs.begin(), xs.end());
xs.erase(unique(xs.begin(), xs.end()), xs.end());
int M = (int)xs.size();
vector<int> z(N);
for (int i = 0; i < N; i++) {
z[i] = lower_bound(xs.begin(), xs.end(), A[i]) - xs.begin();
}
// 値ごとの左右出現数
vector<long long> leftCnt(M, 0), rightCnt(M, 0);
for (int x : z) rightCnt[x]++;
fenwick_tree<long long> bitL(M); // 左側個数
fenwick_tree<long long> bitR(M); // 右側個数
fenwick_tree<long long> prodBIT(M); // left[v] * right[v]
for (int v = 0; v < M; v++) {
bitR.add(v, rightCnt[v]);
}
long long totalProd = 0;
vector<long long> valueAns(M, 0);
long long leftSize = 0;
long long rightSize = N;
for (int i = 0; i < N; i++) {
int x = z[i];
// 現在位置を右側から除去
bitR.add(x, -1);
rightSize--;
rightCnt[x]--;
long long delta = -leftCnt[x];
prodBIT.add(x, delta);
totalProd += delta;
// < a[i]
long long Lless = bitL.sum(0, x);
long long Rless = bitR.sum(0, x);
// > a[i]
long long Lleq = bitL.sum(0, x + 1);
long long Rleq = bitR.sum(0, x + 1);
long long Lgreater = leftSize - Lleq;
long long Rgreater = rightSize - Rleq;
// 両端同値の除外
long long sameLess = prodBIT.sum(0, x);
long long sameGreater =
totalProd - prodBIT.sum(0, x + 1);
long long cnt =
Lless * Rless +
Lgreater * Rgreater -
sameLess -
sameGreater;
valueAns[x] += cnt;
// 現在位置を左側へ追加
long long addDelta = rightCnt[x];
leftCnt[x]++;
bitL.add(x, 1);
prodBIT.add(x, addDelta);
totalProd += addDelta;
leftSize++;
}
// 値ごとの累積和
vector<long long> pref(M + 1, 0);
for (int i = 0; i < M; i++) {
pref[i + 1] = pref[i] + valueAns[i];
}
int Q;
cin >> Q;
while (Q--) {
long long L, R;
cin >> L >> R;
int l = lower_bound(xs.begin(), xs.end(), L) - xs.begin();
int r = upper_bound(xs.begin(), xs.end(), R) - xs.begin();
cout << pref[r] - pref[l] << '\n';
}
}
kwm_t