結果
| 問題 |
No.5010 Better Mo's Algorithm is Needed!! (Unweighted)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-12-17 12:41:42 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 112 ms / 5,000 ms |
| コード長 | 3,194 bytes |
| コンパイル時間 | 3,612 ms |
| 実行使用メモリ | 14,612 KB |
| スコア | 16,596,720,090 |
| 最終ジャッジ日時 | 2022-12-17 12:42:47 |
| 合計ジャッジ時間 | 57,080 ms |
|
ジャッジサーバーID (参考情報) |
judge12 / judge16 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 120 |
ソースコード
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;
#define ll long long int
constexpr double time_limit = 4.8;
struct Input {
int n, q, wt, st;
vector<ll> w;
vector<pair<int,int>> lr;
void input() {
cin >> n >> q >> wt >> st;
w.resize(n);
for (int i = 0; i < n; ++i) {
cin >> w[i];
}
lr.resize(q);
for (int i = 0; i < q; ++i) {
int l, r;
cin >> l >> r;
lr[i] = {l - 1, r - 1};
}
}
};
struct Solver {
int n, q, wt, st;
vector<ll> w;
vector<pair<int,int>> lr;
vector<ll> cs; // cumulative sum of w
vector<int> p;
ll cost;
Solver(const Input& input) {
n = input.n;
q = input.q;
wt = input.wt;
st = input.st;
w = input.w;
lr = input.lr;
// initialize cs
cs.resize(n + 1, 0);
for (int i = 0; i < n; ++i) {
cs[i + 1] = cs[i] + w[i];
}
}
void mo() {
int sqrt_n = (int)sqrt(n) + 1;
vector<vector<pair<int,int>>> groups(sqrt_n + 1);
for (int i = 0; i < q; ++i) {
auto [l, r] = lr[i];
groups[sqrt_n * cs[l] / cs.back()].push_back({r, i});
}
bool flag = false;
for (vector<pair<int,int>>& group : groups) {
if (group.empty()) {
continue;
}
sort(group.begin(), group.end());
if (flag) {
reverse(group.begin(), group.end());
}
for (auto [_, i] : group) {
p.push_back(i);
}
flag ^= true;
}
}
ll get_cost(int i, int j) {
auto [a, b] = lr[i];
auto [c, d] = lr[j];
return cs[max(a, c)] - cs[min(a, c)] + cs[max(b, d) + 1] - cs[min(b, d) + 1];
}
void initialize_cost() {
cost = 0;
for (int i = 0; i < q - 1; ++i) {
cost += get_cost(p[i], p[i + 1]);
}
}
ll reverse_delta(int i, int j) {
ll delta = 0;
delta -= get_cost(p[i - 1], p[i]);
delta -= get_cost(p[j], p[j + 1]);
delta += get_cost(p[i - 1], p[j]);
delta += get_cost(p[i], p[j + 1]);
return delta;
}
void reverse_nodes(int i, int j, ll delta) {
reverse(p.begin() + i, p.begin() + j + 1);
cost += delta;
}
void improve() {
for (int i = 1; i < q - 2; ++i) {
ll delta = reverse_delta(i, i + 1);
if (delta <= 0) {
reverse_nodes(i, i + 1, delta);
}
}
}
void print() {
for (int i = 0; i < q; ++i) {
cout << p[i] + 1;
if (i == q - 1) {
cout << "\n";
} else {
cout << " ";
}
}
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
Input input;
input.input();
Solver solver(input);
solver.mo();
solver.initialize_cost();
solver.improve();
solver.print();
return 0;
}