結果
| 問題 |
No.5010 Better Mo's Algorithm is Needed!! (Unweighted)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-12-18 00:56:54 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 8,537 bytes |
| コンパイル時間 | 2,791 ms |
| 実行使用メモリ | 24,768 KB |
| スコア | 0 |
| 最終ジャッジ日時 | 2022-12-18 00:57:27 |
| 合計ジャッジ時間 | 20,785 ms |
|
ジャッジサーバーID (参考情報) |
judge11 / judge12 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | TLE * 1 -- * 119 |
コンパイルメッセージ
warning: unused macro definition: `debug`
--> Main.rs:88:14
|
88 | macro_rules! debug{
| ^^^^^
|
= note: `#[warn(unused_macros)]` on by default
warning: unused macro definition: `param`
--> Main.rs:152:14
|
152 | macro_rules! param{
| ^^^^^
warning: unused import: `std::mem`
--> Main.rs:203:5
|
203 | use std::mem;
| ^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: field is never read: `st`
--> Main.rs:218:5
|
218 | st:usize,
| ^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: associated function is never used: `score`
--> Main.rs:294:8
|
294 | fn score(&self)->i64{
| ^^^^^
warning: 5 warnings emitted
ソースコード
#![allow(non_snake_case)]
#[allow(unused)]
mod rnd {
static mut S:usize=88172645463325252;
#[inline]
pub fn next()->usize{
unsafe{
S^=S<<7;
S^=S>>9;
S
}
}
#[inline]
pub fn nextf()->f64{
unsafe{
std::mem::transmute::<_,f64>(0x3ff0000000000000|next()&0xfffffffffffff)-1.
}
}
#[inline]
pub fn range(a:usize,b:usize)->usize{
next()%(b-a)+a
}
#[inline]
pub fn exu(a:usize,b:usize,skip:usize)->usize{
let ret=range(a,b-1);
if ret==skip{b-1}
else{ret}
}
#[inline]
pub fn shuffle<T>(list:&mut [T]){
for i in (0..list.len()).rev(){
list.swap(i,next()%(i+1));
}
}
}
#[inline]
fn get_time_secs()->f64{
std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs_f64()
}
struct Timer(f64);
impl Timer{
#[inline]
fn new()->Timer{
Timer(get_time_secs())
}
#[inline]
fn get_time(&self)->f64{
get_time_secs()-self.0
}
}
#[cfg(local)]
#[allow(unused)]
macro_rules! debug{
()=>{
eprintln!();
};
($x:literal)=>{
eprintln!("{:?}",$x);
};
($x:expr)=>{
eprintln!("{}: {:?}",stringify!($x),$x);
};
($x:literal,$($l:expr),*)=>{
eprint!("{:?}, ",$x);
debug!($($l),*);
};
($x:expr,$($l:expr),*)=>{
eprint!("{}: {:?}, ",stringify!($x),$x);
debug!($($l),*);
}
}
#[cfg(not(local))]
macro_rules! debug{
($($_:tt)*)=>{}
}
#[cfg(local)]
macro_rules! log{
()=>{};
($x:literal)=>{
eprintln!("{}",$x);
};
($x:ident $(,)?)=>{
log!(@out $x,$x);
};
($x:ident,$t:ident $(,)?)=>{
log!(@out $x,$x);
log!($t);
};
($x:ident,$($_:ident).* $(,)?)=>{
compile_error!();
};
($x:ident,$t:expr $(,)?)=>{
log!(@out $x,$t);
};
($($x:ident).* $(,)?)=>{
log!(@last $($x).*;$($x).*);
};
($x:ident,$t:ident,$($rest:tt)*)=>{
log!(@out $x,$x);
log!($t,$($rest)*);
};
($x:ident,$($_:ident).*,$($rest:tt)*)=>{
compile_error!();
};
($x:ident,$t:expr,$($rest:tt)*)=>{
log!(@out $x,$t);
log!($($rest)*);
};
($($x:ident).*,$($rest:tt)*)=>{
log!(@last $($x).*;$($x).*);
log!($($rest)*);
};
(@out $x:ident,$t:expr)=>{
eprintln!("{} = {:?}",stringify!($x),$t);
};
(@last $x:ident;$full:expr)=>{
log!(@out $x,$full);
};
(@last $_:ident. $($rest:ident).*;$full:expr)=>{
log!(@last $($rest).*;$full)
}
}
#[cfg(not(local))]
macro_rules! log{
($($_:tt)*)=>{}
}
macro_rules! param{
($($x:ident:$t:ty=$v:literal),* $(,)?)=>{
#[allow(non_snake_case)]
struct Param{
$($x:$t),*
}
impl Param{
#[inline]
fn new()->Self{
Self{
$(
$x:match std::env::var(stringify!($x)){
Ok(s)=>s.parse().expect("parse error"),
Err(_)=>$v
}
),*
}
}
}
};
}
#[allow(unused)]
struct Scanner{
stack:std::str::SplitAsciiWhitespace<'static>
}
#[allow(unused)]
impl Scanner{
#[inline]
fn new()->Self{
Self{stack:"".split_ascii_whitespace()}
}
#[inline]
fn read<T:std::str::FromStr>(&mut self)->T{
loop{
if let Some(v)=self.stack.next(){
return v.parse::<T>().unwrap_or_else(|_|panic!("{}: parse error",std::any::type_name::<T>()));
}
let mut tmp=String::new();
std::io::stdin().read_line(&mut tmp).unwrap();
assert!(!tmp.is_empty());
self.stack=Box::leak(tmp.into_boxed_str()).split_ascii_whitespace();
}
}
}
use std::io::*;
use std::mem;
use std::cmp::Reverse;
const N:usize=200000;
const Q:usize=200000;
#[inline]
fn abs_diff(a:usize,b:usize)->usize{
(a as i64-b as i64).abs() as usize
}
struct Out{
st:usize,
route:Vec<(usize,usize,usize)>
}
impl Out{
#[inline]
fn input()->Out{
let mut scan=Scanner::new();
let n:usize=scan.read();
let q:usize=scan.read();
let wt:usize=scan.read();
let st:usize=scan.read();
assert_eq!((n,q,wt),(N,Q,1));
for _ in 0..n{
scan.read::<usize>();
}
let mut route=Vec::with_capacity(Q);
for i in 0..Q{
let l:usize=scan.read();
let r:usize=scan.read();
route.push((l,r,i));
}
Out{st,route}
}
#[inline]
fn greedy(&mut self){
const D:usize=15;
self.route[1..].sort_unstable();
let mut block0=vec![Vec::with_capacity(Q/D);D];
let w=Q/D;
for i in 0..Q{
block0[(i/w).min(D-1)].push(self.route[i]);
}
let mut block1=vec![vec![Vec::with_capacity(Q/(D*D));D];D];
for i in 0..D{
block0[i].sort_unstable_by_key(|(_,r,_)|*r);
let w=block0[i].len()/D;
for j in 0..block0[i].len(){
block1[i][(j/w).min(D-1)].push(block0[i][j]);
}
}
let mut blocks=Vec::with_capacity(D*D);
for (i,b0) in block1.into_iter().enumerate(){
for (j,b1) in b0.into_iter().enumerate(){
blocks.push((i,j,b1));
}
}
blocks.sort_unstable_by_key(|&(y,x,_)|{
if D&1!=y&1{
Reverse((y,!x))
}
else{
Reverse((y,x))
}
});
self.route.clear();
for (_,_,mut block) in blocks{
while !block.is_empty(){
let arg_max=if self.route.is_empty(){
(0..block.len()).min_by_key(|&i|self.get_first(block[i])).unwrap()
}
else{
let last=self.route.last().unwrap().clone();
(0..block.len()).min_by_key(|&i|self.get(last,block[i])).unwrap()
};
self.route.push(block.swap_remove(arg_max));
}
}
assert_eq!(self.route.len(),Q);
}
#[inline]
fn score(&self)->i64{
let mut ret=self.get_first(self.route[0]);
for i in 1..self.route.len(){
ret+=self.dist(i-1,i);
}
ret as i64
}
#[inline]
fn get_first(&self,(l,r,_):(usize,usize,usize))->usize{
l-r
}
#[inline]
fn get(&self,(l0,r0,_):(usize,usize,usize),(l1,r1,_):(usize,usize,usize))->usize{
abs_diff(l0,l1)+abs_diff(r0,r1)
}
#[inline]
fn dist(&self,a:usize,b:usize)->usize{
self.get(self.route[a],self.route[b])
}
#[inline]
fn try_2opt(&self,a:usize,b:usize)->i64{
let old=self.dist(a-1,a)+self.dist(b-1,b);
let new=self.dist(a-1,b-1)+self.dist(a,b);
(new-old) as i64
}
#[inline]
fn apply_2opt(&mut self,a:usize,b:usize){
self.route[a..b].reverse()
}
}
const TL:f64=4.98;
fn hc(out:&mut Out,d:usize){
for a in 1..Q-d{
for b in a+2..a+d{
let diff=out.try_2opt(a,b);
if diff<=0{
out.apply_2opt(a,b);
}
}
}
log!(score,out.score() as f64/1e6);
}
fn hc_with_timer(out:&mut Out,time:&Timer,d:usize){
let mut iter=0;
for a in 1..Q-d{
for b in a+2..a+d{
if iter&255==0 && time.get_time()>=TL{
return;
}
iter+=1;
let diff=out.try_2opt(a,b);
if diff<=0{
out.apply_2opt(a,b);
}
}
}
log!(score,out.score() as f64/1e6);
}
fn main(){
let time=Timer::new();
let mut out=Out::input();
out.greedy();
log!(init_score,out.score() as f64/1e6);
hc(&mut out,1500);
hc(&mut out,1500);
hc(&mut out,1200);
hc(&mut out,1200);
hc_with_timer(&mut out,&time,600);
hc_with_timer(&mut out,&time,600);
hc_with_timer(&mut out,&time,300);
hc_with_timer(&mut out,&time,300);
hc_with_timer(&mut out,&time,300);
hc_with_timer(&mut out,&time,1000);
let stdout=stdout();
let stdout=&mut BufWriter::new(stdout.lock());
for (_,_,id) in &out.route{
writeln!(stdout,"{}",id+1).unwrap();
}
stdout.flush().unwrap();
}