結果
| 問題 |
No.5011 Better Mo's Algorithm is Needed!! (Weighted)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-12-17 12:53:00 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 4,991 ms / 5,000 ms |
| コード長 | 7,875 bytes |
| コンパイル時間 | 2,606 ms |
| 実行使用メモリ | 15,432 KB |
| スコア | 35,017,118,496 |
| 最終ジャッジ日時 | 2022-12-17 13:03:49 |
| 合計ジャッジ時間 | 647,165 ms |
|
ジャッジサーバーID (参考情報) |
judge14 / judge10 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 120 |
コンパイルメッセージ
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: unused variable: `p`
--> Main.rs:366:9
|
366 | let p=up as f64/iter as f64;
| ^ help: if this is intentional, prefix it with an underscore: `_p`
|
= note: `#[warn(unused_variables)]` on by default
warning: function is never used: `abs_diff`
--> Main.rs:223:4
|
223 | fn abs_diff(a:usize,b:usize)->usize{
| ^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: field is never read: `wt`
--> Main.rs:229:5
|
229 | wt:usize,
| ^^^^^^^^
warning: field is never read: `st`
--> Main.rs:230:5
|
230 | st:usize,
| ^^^^^^^^
warning: associated function is never used: `score`
--> Main.rs:283:8
|
283 | fn score(&self)->i64{
| ^^^^^
warning: 8 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 min_max(a:usize,b:usize)->(usize,usize){
if a>b{
(b,a)
}
else{
(a,b)
}
}
#[inline]
fn abs_diff(a:usize,b:usize)->usize{
(a as i64-b as i64).abs() as usize
}
struct Out{
wt:usize,
st:usize,
sum:Vec<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),(N,Q));
let mut sum=Vec::with_capacity(N);
sum.push(0);
let mut last=0;
for _ in 0..n{
let v:usize=scan.read();
last+=v;
sum.push(last);
}
let mut route=Vec::with_capacity(Q);
let mut max_score=(0,0,Reverse(!0));
let mut arg_max=!0;
for i in 0..Q{
let l:usize=scan.read();
let r=scan.read::<usize>()-1;
route.push((l,r,i));
let score=(l>>9,r>>9,Reverse(sum[r]-sum[l]));
if max_score<score{
max_score=score;
arg_max=i;
}
}
route.swap(0,arg_max);
route[1..].sort_unstable_by_key(|&(l,r,_)|{
Reverse(
if l>>9&1==0{
(l>>9,(r>>9) as i64,l.pow(3)+r.pow(3))
}
else{
(l>>9,-((r>>9) as i64),l.pow(3)+r.pow(3))
}
)
});
Out{wt,st,sum,route}
}
#[inline]
fn score(&self)->i64{
let mut ret=self.sum[self.route[0].1]-self.sum[self.route[0].0];
for i in 1..self.route.len(){
ret+=self.dist(i-1,i);
}
ret as i64
}
#[inline]
fn dist(&self,a:usize,b:usize)->usize{
let (l0,r0,_)=self.route[a];
let (l1,r1,_)=self.route[b];
let (l0,l1)=min_max(l0,l1);
let (r0,r1)=min_max(r0,r1);
self.sum[l1]-self.sum[l0]+self.sum[r1]-self.sum[r0]
}
#[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()
}
}
fn sa(out:&mut Out,time:&Timer){
let mut score=0;
let mut best=score;
let mut iter=0;
let mut up=0;
let mut th=[0;256];
let mut a=0;
const D:usize=500;
loop{
if iter&1023==0{
const TL:f64=4.98;
let p=time.get_time()/TL;
if p>=1.{break;}
const T0:f64=5000.;
const T1:f64=0.;
let heat=T0+(T1-T0)*p;
let mut id=0;
while{
th[id]=(-heat*rnd::nextf().ln()) as i64;
th[id+1]=(-heat*rnd::nextf().ln()) as i64;
id+=2;
id<th.len()
}{}
}
iter+=1;
a+=1;
if Q-D-1<=a{
a=1;
}
let b=a+rnd::next()%D+1;
let diff=out.try_2opt(a,b);
if diff<=th[iter&255]{
out.apply_2opt(a,b);
score+=diff;
up+=1;
best=best.min(score);
}
}
let p=up as f64/iter as f64;
log!(score,best,iter,iter as f64/1e7,p);
log!(scoref,out.score() as f64/5e7);
}
fn main(){
let time=Timer::new();
let mut out=Out::input();
log!(init_score,out.score() as f64/5e7);
sa(&mut out,&time);
let stdout=stdout();
let stdout=&mut BufWriter::new(stdout.lock());
for (_,_,id) in &out.route{
writeln!(stdout,"{}",id+1).unwrap();
}
stdout.flush().unwrap();
}