結果
| 問題 |
No.878 Range High-Element Query
|
| コンテスト | |
| ユーザー |
MarcusAureliusAntoninus
|
| 提出日時 | 2019-09-06 23:19:07 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 91 ms / 2,000 ms |
| コード長 | 3,648 bytes |
| コンパイル時間 | 2,546 ms |
| コンパイル使用メモリ | 205,796 KB |
| 最終ジャッジ日時 | 2025-01-07 16:58:30 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 18 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:100:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
100 | scanf("%d%d", &N, &Q);
| ~~~~~^~~~~~~~~~~~~~~~
main.cpp:102:31: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
102 | for (auto& e: a) scanf("%d", &e);
| ~~~~~^~~~~~~~~~
main.cpp:121:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
121 | scanf("%d%d%d", &com, &left, &right);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ソースコード
#include <bits/stdc++.h>
/////////////////////////
// Range Maximum Query //
/////////////////////////
class RMaxQ {
private:
std::vector<int64_t> container_;
const int64_t negative_inf_{-1};
void build(const unsigned int array_size)
{
unsigned int length{1};
while (length < array_size)
length <<= 1;
container_.resize(2 * length, negative_inf_);
}
public:
RMaxQ(const unsigned int array_size) { build(array_size); }
RMaxQ(const std::vector<int64_t> &array)
{
build(array.size());
std::copy(array.begin(), array.end(), container_.begin() + (container_.size() >> 1));
for (auto i{(container_.size() >> 1) - 1}; i > 0; i--)
container_[i] = std::max(container_[2 * i], container_[2 * i + 1]);
}
// indexは0-indexed
void update(const int index, const int64_t assigned)
{
auto update_place{(container_.size() >> 1) + index};
container_[update_place] = assigned;
while (update_place > 1)
{
update_place >>= 1;
container_[update_place] = std::max(container_[2 * update_place], container_[2 * update_place + 1]);
}
}
// left,rightは0-indexed、[left, right)の半開区間
int64_t get(const int left, const int right) const
{
int64_t max{negative_inf_};
for (int left_i{std::max(0, left) + ((int)container_.size() >> 1)}, right_i{std::min((int)container_.size() >> 1, right) + ((int)container_.size() >> 1)};
left_i < right_i; left_i >>= 1, right_i >>= 1
)
{
if (left_i & 1)
{
max = std::max(max, container_[left_i]);
left_i++;
}
if (right_i & 1)
{
right_i--;
max = std::max(max, container_[right_i]);
}
}
return max;
}
};
///////////////////////////
// Range Sum Query (BIT) //
///////////////////////////
class RSumQBIT {
private:
std::vector<int64_t> container_;
int64_t getHelper(const int index) const
{
if (index < 0) return 0;
if ((int)(container_.size()) <= index) return container_.back();
int64_t sum{};
for (int add_place{index}; add_place > 0; add_place -= add_place & -add_place)
sum += container_[add_place];
return sum;
}
public:
RSumQBIT(const int array_size)
: container_(array_size + 1) {}
// indexは0-indexed
void update(const int index, const int64_t added)
{
for (int update_place{index + 1}; update_place < (int)(container_.size()); update_place += update_place & -update_place)
container_[update_place] += added;
}
// left,rightは0-indexed、[left, right)の半開区間
int64_t get(const int left, const int right) const
{
return -getHelper(left) + getHelper(right);
}
};
int main()
{
int N, Q;
scanf("%d%d", &N, &Q);
std::vector<int> a(N);
for (auto& e: a) scanf("%d", &e);
std::vector<int> prev(N, -1);
RMaxQ myHome(N);
for (int i{}; i < N; i++)
{
a[i]--;
prev[i] = myHome.get(a[i] + 1, N);
myHome.update(a[i], i);
}
// for (auto& e: prev) printf("%d ", e);
// putchar('\n');
std::vector<std::array<int64_t, 4>> queries(N + Q);
// {1, left, right, q_i}
// {2, prev, index, -1}
for (int i{}; i < N; i++)
queries[i] = {2, prev[i], i, -1};
for (int i{}; i < Q; i++)
{
int com, left, right;
scanf("%d%d%d", &com, &left, &right);
left--;
queries[N + i] = {1, left, right, i};
}
std::sort(queries.begin(), queries.end(), [](auto& a, auto& b) {
if (a[1] != b[1]) return a[1] < b[1];
else return a[0] < b[0];
});
// for (auto& e: queries)
// {
// for (auto& f: e) printf("%d ", f);
// putchar('\n');
// }
RSumQBIT bit(N);
std::vector<int> ans(Q);
for (auto& query: queries)
{
if (query[0] == 1)
ans[query[3]] = bit.get(query[1], query[2]);
else
bit.update(query[2], 1);
}
for (auto& e: ans) printf("%d\n", e);
return 0;
}
MarcusAureliusAntoninus