結果
| 問題 |
No.3059 Range Tournament
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-07-07 19:48:46 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 749 ms / 4,000 ms |
| コード長 | 2,092 bytes |
| コンパイル時間 | 3,084 ms |
| コンパイル使用メモリ | 260,144 KB |
| 実行使用メモリ | 39,808 KB |
| 最終ジャッジ日時 | 2024-07-07 19:49:11 |
| 合計ジャッジ時間 | 20,875 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 27 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#include "atcoder/segtree.hpp"
using S = int;
S op(S l, S r) {
return l > r ? l : r;
}
S e() {
return -1;
}
int main() {
int n;
cin >> n;
assert(2 <= n and n <= 200000);
vector<bool> used(n);
vector<int> P(n);
for (int i = 0; i < n; i++) {
cin >> P[i];
assert(1 <= P[i] <= n);
P[i]--;
assert(!used[P[i]]);
used[P[i]] = true;
}
int Q;
cin >> Q;
assert(1 <= Q and Q <= 200000);
atcoder::segtree<S, op, e> seg(P);
vector<int> ans(n, 0);
vector<vector<int>> imos(20, vector<int>(2 * n, 0));
while (Q--) {
int l, r;
cin >> l >> r;
assert(1 <= l and l < r and r <= n);
l--;
int d = r - l;
vector<pair<int, int>> rle;
rle.emplace_back(1, d);
int k = d - 1;
int p = 0;
int minus = 0;
while (k > 0) {
int c = (rle[p].second - minus) / 2;
minus = rle[p].second - minus - 2 * c;
if (c != 0) {
rle.emplace_back(rle[p].first * 2, c);
}
k -= c;
if (minus == 1) {
rle.emplace_back(rle[p].first + rle[p + 1].first, 1);
k--;
}
p++;
}
int s = 0;
int p2 = 1;
for (size_t i = 1; i < rle.size(); i++) {
auto [c, t] = rle[i];
int l_ = s;
int r_ = s + c * t;
if (r_ <= d) {
imos[p2][l + l_]++;
imos[p2][l + r_]--;
p2++;
} else {
int ma = max(seg.prod(l + l_, r), seg.prod(l, l + r_ - d));
ans[ma]++;
}
s = r_ % d;
}
}
for (int i = 1; i < 20; i++) {
int d = 1 << i;
for (int j = 0; j <= n - d; j++) {
imos[i][j + d] += imos[i][j];
auto ma = seg.prod(j, j + d);
ans[ma] += imos[i][j];
}
}
for (auto x : ans) cout << x << '\n';
}