結果
| 問題 |
No.919 You Are A Project Manager
|
| コンテスト | |
| ユーザー |
akakimidori
|
| 提出日時 | 2020-07-04 11:03:59 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 152 ms / 3,000 ms |
| コード長 | 6,403 bytes |
| コンパイル時間 | 29,105 ms |
| コンパイル使用メモリ | 378,156 KB |
| 実行使用メモリ | 13,540 KB |
| 最終ジャッジ日時 | 2024-09-18 19:15:49 |
| 合計ジャッジ時間 | 20,215 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 55 |
ソースコード
// ---------- begin Mo algorithm ----------
pub trait MoOperator {
type Value;
type Query;
type Answer;
fn init(&mut self);
fn insert(&mut self, v: &Self::Value);
fn delete(&mut self, v: &Self::Value);
fn answer(&mut self, q: &Self::Query) -> Self::Answer;
}
pub struct MoSolver<State: MoOperator> {
state: State,
array: Vec<State::Value>,
query: Vec<(usize, usize, State::Query)>,
}
impl<State: MoOperator> MoSolver<State> {
fn new(state: State, array: Vec<State::Value>) -> Self {
MoSolver {
state: state,
array: array,
query: vec![],
}
}
#[allow(dead_code)]
fn add(&mut self, l: usize, r: usize, q: State::Query) {
assert!(l < r && r <= self.array.len());
self.query.push((l, r, q));
}
fn solve(&mut self, answer: &mut [State::Answer]) {
assert!(self.query.len() <= answer.len());
if self.query.is_empty() {
return;
}
let size = self.array.len();
let batch = {
let b = (size as f64 / (self.query.len() as f64).sqrt()).ceil() as usize;
if b > size {
size
} else {
b
}
};
let mut q = (0..(size / batch + 1)).map(|_| vec![]).collect::<Vec<_>>();
let mut query = vec![];
std::mem::swap(&mut query, &mut self.query);
for (k, (l, r, op)) in query.into_iter().enumerate() {
q[l / batch].push((r, l, k, op));
}
let state = &mut self.state;
state.init();
let mut x = 0;
let mut y = 0;
for (i, q) in q.iter_mut().enumerate() {
q.sort_by_key(|p| p.0);
if i % 2 == 1 {
q.reverse();
}
for p in q.iter() {
let (r, l, k) = (p.0, p.1, p.2);
for v in self.array[std::cmp::min(y, r)..r].iter() {
state.insert(v);
y = r;
}
for v in self.array[std::cmp::min(l, x)..x].iter().rev() {
state.insert(v);
x = l;
}
for v in self.array[std::cmp::min(r, y)..y].iter().rev() {
state.delete(v);
y = r;
}
for v in self.array[std::cmp::min(x, l)..l].iter() {
state.delete(v);
x = l;
}
answer[k] = state.answer(&p.3);
}
}
}
}
// ---------- end Mo algorithm ----------
// ---------- begin fenwick tree ----------
#[allow(dead_code)]
mod fenwick {
type T = i32;
const ZERO: T = 0;
pub struct Tree {
a: Box<[T]>,
}
impl Tree {
pub fn new(n: usize) -> Tree {
Tree {
a: vec![ZERO; n + 1].into_boxed_slice(),
}
}
pub fn init(&mut self) {
for a in self.a.iter_mut() {
*a = ZERO;
}
}
pub fn add(&mut self, mut x: usize, v: T) {
assert!(x > 0);
while let Some(a) = self.a.get_mut(x) {
*a += v;
x += x & (!x + 1);
}
}
pub fn sum(&self, mut x: usize) -> T {
assert!(x < self.a.len());
let mut res = ZERO;
while x > 0 {
res += self.a[x];
x -= x & (!x + 1);
}
res
}
pub fn search(&self, s: T) -> usize {
debug_assert!(self.sum(self.a.len() - 1) >= s);
let mut k = 1;
while 2 * k < self.a.len() {
k *= 2;
}
let mut x = 0;
let mut w = ZERO;
while k > 0 {
self.a.get(x + k).map(|a| {
if w + *a < s {
w += *a;
x += k;
}
});
k >>= 1;
}
x + 1
}
}
}
// ---------- end fenwick tree ----------
use std::io::Read;
struct State {
bit: fenwick::Tree,
cnt: i32,
}
impl MoOperator for State {
type Value = usize;
type Query = ();
type Answer = usize;
fn init(&mut self) {
self.bit.init();
self.cnt = 0;
}
fn insert(&mut self, v: &Self::Value) {
self.bit.add(*v, 1);
self.cnt += 1;
}
fn delete(&mut self, v: &Self::Value) {
self.bit.add(*v, -1);
self.cnt -= 1;
}
fn answer(&mut self, _q: &Self::Query) -> Self::Answer {
self.bit.search((self.cnt + 1) / 2)
}
}
fn run() {
let mut s = String::new();
std::io::stdin().read_to_string(&mut s).unwrap();
let a: Vec<i64> = s.trim().split_whitespace().skip(1).map(|s| s.parse().unwrap()).collect();
let mut b = a.clone();
b.push(std::i64::MIN);
b.sort();
b.dedup();
let a = a.into_iter().map(|a| b.binary_search(&a).unwrap()).collect::<Vec<_>>();
let n = a.len();
let state = State {
bit: fenwick::Tree::new(b.len() - 1),
cnt: 0,
};
let mut solver = MoSolver::new(state, a);
let mut query = vec![];
for w in 1..=n {
for j in 0..(n / w) {
query.push((j * w, (j + 1) * w, ()));
query.push((n - (j + 1) * w, n - j * w, ()));
}
}
query.sort();
query.dedup();
let mut index = vec![0; query.len()];
solver.query = query.clone();
solver.solve(&mut index);
let mut ans = 0;
for w in 1..=n {
let mut left = vec![0i64];
let mut right = vec![0i64];
for j in 0..(n / w) {
let k = query.binary_search(&(j * w, (j + 1) * w, ())).unwrap();
let v = b[index[k]] + *left.last().unwrap();
left.push(v);
let k = query.binary_search(&(n - (j + 1) * w, n - j * w, ())).unwrap();
let v = b[index[k]] + *right.last().unwrap();
right.push(v);
}
for i in 1..left.len() {
left[i] = std::cmp::max(left[i], left[i - 1]);
right[i] = std::cmp::max(right[i], right[i - 1]);
}
for (l, r) in left.iter().zip(right.iter().rev()) {
ans = std::cmp::max(ans, w as i64 * (*l + *r));
}
}
println!("{}", ans);
}
fn main() {
run();
}
akakimidori