結果
| 問題 |
No.5002 stick xor
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-06-14 01:16:28 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 982 ms / 1,000 ms |
| コード長 | 11,311 bytes |
| コンパイル時間 | 1,350 ms |
| 実行使用メモリ | 2,748 KB |
| スコア | 52,795 |
| 最終ジャッジ日時 | 2022-06-14 01:17:04 |
| 合計ジャッジ時間 | 36,242 ms |
|
ジャッジサーバーID (参考情報) |
judge13 / judge14 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 32 |
コンパイルメッセージ
warning: unused variable: `p`
--> Main.rs:450:9
|
450 | 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: unused `Result` that must be used
--> Main.rs:169:21
|
169 | writeln!(stdout,"{} {} {} {}",y,x,y,x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: this `Result` may be an `Err` variant, which should be handled
= note: this warning originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unused `Result` that must be used
--> Main.rs:172:21
|
172 | writeln!(stdout,"1 1 1 1");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
= note: this warning originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unused `Result` that must be used
--> Main.rs:180:21
|
180 | writeln!(stdout,"{} {} {} {}",id,s,id,t);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
= note: this warning originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unused `Result` that must be used
--> Main.rs:183:21
|
183 | writeln!(stdout,"{} {} {} {}",s,id,t,id);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
= note: this warning originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: 5 warnings emitted
ソースコード
#[allow(unused)]
mod rnd {
static mut S:usize=88172645463325252;
#[inline]
pub fn next()->usize{
unsafe{
S=S^S<<7;
S=S^S>>9;
S
}
}
#[inline]
pub fn nextf()->f64{
(next()&4294967295) as f64/4294967296.
}
}
#[allow(unused)]
#[inline]
fn get_time()->f64{
static mut START:f64=-1.;
let t=std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs_f64();
unsafe{
if START<0.{START=t;}
t-START
}
}
#[cfg(local)]
#[allow(unused)]
macro_rules! debug{
($x:expr)=>{
eprintln!("{}: {:?}",stringify!($x),$x);
};
($x:expr,$($l:expr),*)=>{
eprint!("{}: {:?}, ",stringify!($x),$x);
debug!($($l),*);
}
}
#[cfg(not(local))]
#[allow(unused)]
macro_rules! debug{
($($_:expr),*)=>{}
}
const N:usize=60;
const K:usize=500;
const M:usize=26;
struct In{
l:[usize;K],
target:Vec<usize>,
len:[Vec<usize>;M]
}
impl In{
fn input()->(In,[[bool;N];N]){
use std::io::Read;
let mut input="".to_owned();
std::io::stdin().read_to_string(&mut input).unwrap();
let mut input=input.split_ascii_whitespace();
macro_rules! read(($ty:ty) => (input.next().unwrap().parse::<$ty>().unwrap()));
let n=read!(usize);
let k=read!(usize);
assert_eq!((n,k),(N,K));
let mut l=[!0;K];
let mut target=vec![];
let mut len=[();M].map(|_|vec![]);
for i in 0..K{
let length=read!(usize);
l[i]=length;
if length!=1{
len[length].push(target.len());
target.push(length);
}
}
let mut grid=[[false;N];N];
for i in 0..N{
let s=read!(String);
for (j,v) in s.chars().enumerate(){
grid[i][j]=v=='0';
}
}
(In{l,target,len},grid)
}
}
struct Out{
state:[[bool;N];N],
out:Vec<(bool,usize,usize,usize)>, // $0==true := 横向き ($2,$3) := (始点,終点)
temp:[(bool,usize);N*2]
}
impl Out{
#[inline]
fn new(input:&In,mut state:[[bool;N];N])->Out{
let mut out=vec![];
for &l in input.target.iter(){
let idx=rnd::next()%N;
let s=rnd::next()%(N-l);
let t=s+l;
let f=rnd::next()&1==0;
out.push((f,idx,s,t));
for j in s..t{
if f{
state[idx][j]=!state[idx][j];
}
else{
state[j][idx]=!state[j][idx];
}
}
}
let mut temp=[(false,!0);N*2];
for i in 0..N*2{
temp[i].0=i<N;
temp[i].1=i%N;
}
Out{state,out,temp}
}
#[inline]
// 白マスの個数
fn score(&self)->i64{
let mut ret=0;
for i in 0..N{
for j in 0..N{
ret+=self.state[i][j] as i64;
}
}
ret
}
#[inline]
fn print(&self,input:&In){
use std::io::Write;
let stdout=std::io::stdout();
let stdout=&mut std::io::BufWriter::new(stdout.lock());
let mut kuro=vec![];
for i in 0..N{
for j in 0..N{
if !self.state[i][j]{
kuro.push((i+1,j+1));
}
}
}
let mut idx=0;
for &l in input.l.iter(){
if l==1{
if let Some((y,x))=kuro.pop(){
writeln!(stdout,"{} {} {} {}",y,x,y,x);
}
else{
writeln!(stdout,"1 1 1 1");
}
}
else{
let (f,id,s,t)=self.out[idx];
let id=id+1;
let s=s+1;
if f{
writeln!(stdout,"{} {} {} {}",id,s,id,t);
}
else{
writeln!(stdout,"{} {} {} {}",s,id,t,id);
}
idx+=1;
}
}
stdout.flush().unwrap();
}
}
impl Out{
#[inline]
fn shift(&mut self,add:i64,id:usize,score:&mut i64)->bool{
let (f,idx,mut s,mut t)=self.out[id];
if t==N || s!=0 && rnd::next()&1==0{
s-=1;
t-=1;
}
let p1;
let p2;
let diff=if f{
(p1,p2)=((idx,s),(idx,t));
2-((self.state[idx][s] as i64+self.state[idx][t] as i64)<<1)
}
else{
(p1,p2)=((s,idx),(t,idx));
2-((self.state[s][idx] as i64+self.state[t][idx] as i64)<<1)
};
if add<=diff{
*score+=diff;
self.state[p1.0][p1.1]=!self.state[p1.0][p1.1];
self.state[p2.0][p2.1]=!self.state[p2.0][p2.1];
let a=(((self.out[id].2==s) as usize)<<1)-1;
self.out[id].2+=a;
self.out[id].3+=a;
true
}
else{
false
}
}
#[inline]
// l+1 == len(id1)+1 == len(id2)
fn swap_sub(&mut self,add:i64,l:usize,id1:usize,id2:usize,score:&mut i64)->bool{
let mut diff=0;
let (f1,idx1,mut s1,t1)=self.out[id1];
let p1;
diff+=if s1==0 || t1!=N && rnd::next()&1==0{
if f1{
self.state[idx1][t1]=!self.state[idx1][t1];
p1=(idx1,t1);
!self.state[idx1][t1]
}
else{
self.state[t1][idx1]=!self.state[t1][idx1];
p1=(t1,idx1);
!self.state[t1][idx1]
}
}
else{
s1-=1;
if f1{
self.state[idx1][s1]=!self.state[idx1][s1];
p1=(idx1,s1);
!self.state[idx1][s1]
}
else{
self.state[s1][idx1]=!self.state[s1][idx1];
p1=(s1,idx1);
!self.state[s1][idx1]
}
} as i64;
let (f2,idx2,s2,mut t2)=self.out[id2];
let p2;
diff+=if rnd::next()&1==0{
if f2{
p2=(idx2,s2);
self.state[idx2][s2]
}
else{
p2=(s2,idx2);
self.state[s2][idx2]
}
}
else{
t2-=1;
if f2{
p2=(idx2,t2);
self.state[idx2][t2]
}
else{
p2=(t2,idx2);
self.state[t2][idx2]
}
} as i64;
let diff=(1-diff)<<1;
if add<=diff{
*score+=diff;
self.state[p2.0][p2.1]=!self.state[p2.0][p2.1];
self.out.swap(id1,id2);
(self.out[id1].2,self.out[id1].3)=(t2-l,t2);
(self.out[id2].2,self.out[id2].3)=(s1,s1+l+1);
true
}
else{
self.state[p1.0][p1.1]=!self.state[p1.0][p1.1];
false
}
}
#[inline]
fn swap(&mut self,input:&In,add:i64,mut id:usize,score:&mut i64)->bool{
let mut l=input.target[id];
let nd;
if l==2 || l!=M-1 && rnd::next()&1==0{
let kouho=&input.len[l+1];
nd=kouho[rnd::next()%kouho.len()]
}
else{
l-=1;
let kouho=&input.len[l];
nd=id;
id=kouho[rnd::next()%kouho.len()]
}
self.swap_sub(add,l,id,nd,score)
}
#[inline]
fn set_best(&mut self,add:i64,id:usize,r:usize,score:&mut i64)->bool{
let cur=(self.out[id].0,self.out[id].1);
let (s,t)=(self.out[id].2,self.out[id].3);
let mut before=0;
if cur.0{
for i in s..t{
before+=1-((self.state[cur.1][i] as i64)<<1);
self.state[cur.1][i]=!self.state[cur.1][i];
}
}
else{
for i in s..t{
before+=1-((self.state[i][cur.1] as i64)<<1);
self.state[i][cur.1]=!self.state[i][cur.1];
}
}
for i in (0..N<<1).rev(){
self.temp.swap(i,rnd::next()%(i+1));
let (f,idx)=self.temp[i];
if cur!=(f,idx){
let mut diff=before;
if f{
for j in 0..r{
diff+=1-((self.state[idx][j] as i64)<<1);
}
let mut p=0;
while{
if add<=diff{
self.out[id]=(f,idx,p,r+p);
*score+=diff;
for i in p..r+p{
self.state[idx][i]=!self.state[idx][i];
}
return true;
}
p<N-r
}{
diff+=(self.state[idx][p] as i64-self.state[idx][r+p] as i64)<<1;
p+=1;
}
}
else{
for j in 0..r{
diff+=1-((self.state[j][idx] as i64)<<1);
}
let mut p=0;
while{
if add<=diff{
self.out[id]=(f,idx,p,r+p);
*score+=diff;
for i in p..r+p{
self.state[i][idx]=!self.state[i][idx];
}
return true;
}
p<N-r
}{
diff+=(self.state[p][idx] as i64-self.state[p+r][idx] as i64)<<1;
p+=1;
}
}
}
}
if cur.0{
for i in s..t{
self.state[cur.1][i]=!self.state[cur.1][i];
}
}
else{
for i in s..t{
self.state[i][cur.1]=!self.state[i][cur.1];
}
}
false
}
}
fn sa(input:&In,state:[[bool;N];N])->Out{
let mut out=Out::new(input,state);
let mut score=out.score();
let mut best=score;
let mut iter=0;
let mut up=0;
let mut th=[0;256];
let mut idx=0;
loop{
if iter&2047==0{
const TL:f64=0.98;
let p=get_time()/TL;
if p>=1.{break;}
const T:f64=0.8;
let heat=T*(1.-p);
th.fill_with(||(heat*rnd::nextf().ln()) as i64);
}
iter+=1;
idx+=1;
if idx==input.target.len(){idx=0;}
let r=rnd::next();
up+=if r&255==0 && input.target[idx]<=4{ out.set_best(th[iter&255],idx,input.target[idx],&mut score) }
else if r&1==0{ out.shift(th[iter&255],idx,&mut score) }
else{ out.swap(input,th[iter&255],idx,&mut score) } as usize;
best=best.max(score);
}
let p=up as f64/iter as f64;
debug!(iter,p);
debug!(score,best);
assert_eq!(score,out.score());
out
}
fn main(){
let (input,state)=In::input();
let ans=sa(&input,state);
ans.print(&input);
}