結果
| 問題 |
No.1226 I hate Robot Arms
|
| コンテスト | |
| ユーザー |
akakimidori
|
| 提出日時 | 2020-09-11 22:11:34 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 98 ms / 2,000 ms |
| コード長 | 5,863 bytes |
| コンパイル時間 | 10,918 ms |
| コンパイル使用メモリ | 398,928 KB |
| 実行使用メモリ | 15,108 KB |
| 最終ジャッジ日時 | 2025-01-01 21:10:10 |
| 合計ジャッジ時間 | 18,259 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 28 |
ソースコード
//---------- begin SegmentTree Point update Range query ----------
pub trait PURQ {
type T: Clone;
fn fold(l: &Self::T, r: &Self::T) -> Self::T;
fn e() -> Self::T;
}
struct SegmentTreePURQ<R: PURQ> {
seg: Vec<R::T>,
size: usize,
}
#[allow(dead_code)]
impl<R: PURQ> SegmentTreePURQ<R> {
fn new(n: usize) -> SegmentTreePURQ<R> {
let size = n.next_power_of_two();
SegmentTreePURQ {
seg: vec![R::e(); 2 * size],
size: size,
}
}
fn build_by(a: &[R::T]) -> SegmentTreePURQ<R> {
let size = a.len().next_power_of_two();
let mut b = vec![R::e(); 2 * size];
for i in 0..a.len() {
b[i + size] = a[i].clone();
}
let mut seg = SegmentTreePURQ { seg: b, size: size };
seg.update_all();
seg
}
fn update(&mut self, x: usize, v: R::T) {
assert!(x < self.size);
let mut x = x + self.size;
let a = &mut self.seg;
a[x] = v;
x >>= 1;
while x > 0 {
a[x] = R::fold(&a[2 * x], &a[2 * x + 1]);
x >>= 1;
}
}
fn update_tmp(&mut self, x: usize, v: R::T) {
self.seg[self.size + x] = v;
}
fn update_all(&mut self) {
let a = &mut self.seg;
for i in (1..self.size).rev() {
a[i] = R::fold(&a[2 * i], &a[2 * i + 1]);
}
}
fn find(&self, l: usize, r: usize) -> R::T {
assert!(l <= r && r <= self.size);
let mut x = R::e();
let mut y = R::e();
let mut l = l + self.size;
let mut r = r + self.size;
let a = &self.seg;
while l < r {
if l & 1 == 1 {
x = R::fold(&x, &a[l]);
l += 1;
}
if r & 1 == 1 {
r -= 1;
y = R::fold(&a[r], &y);
}
l >>= 1;
r >>= 1;
}
R::fold(&x, &y)
}
// f(a[l..k]) がkについてfalse, false, ..., true みたいに単調であるとした時
// 戻り値xは
// f(&a[l..x]) = false
// f(&a[l..=x]) = true
// を満たす
fn search_right<F>(&self, l: usize, f: F) -> usize
where
F: Fn(&R::T) -> bool,
{
let a = &self.seg;
let mut v = R::e();
let mut r = self.size * 2;
let mut l = l + self.size;
while l < r {
if l & 1 == 1 {
let u = R::fold(&v, &a[l]);
if f(&u) {
break;
}
l += 1;
v = u;
}
l >>= 1;
r >>= 1;
}
if l == r {
return self.size;
}
while l < self.size {
let x = 2 * l;
let u = R::fold(&v, &a[x]);
if f(&u) {
l = x;
} else {
l = x + 1;
v = u;
}
}
l - self.size
}
}
//---------- end SegmentTree Point update Range query ----------
// ---------- begin scannner ----------
#[allow(dead_code)]
mod scanner {
use std::str::FromStr;
use std::str::SplitWhitespace;
use std::io::Read;
use std;
pub struct Scanner<'a> {
it: SplitWhitespace<'a>
}
impl<'a> Scanner<'a> {
pub fn new(s: &'a String) -> Scanner<'a> {
Scanner {
it: s.split_whitespace()
}
}
pub fn next<T: FromStr>(&mut self) -> T {
match self.it.next().unwrap().parse::<T>() {
Ok(v) => v,
_ => panic!("Scanner error")
}
}
pub fn next_chars(&mut self) -> Vec<char> {
self.next::<String>().chars().collect()
}
pub fn next_vec<T: FromStr>(&mut self, len: usize) -> Vec<T> {
(0..len).map(|_| self.next()).collect()
}
}
pub fn read_string() -> String {
let mut s = String::new();
std::io::stdin().read_to_string(&mut s).unwrap();
s
}
}
// ---------- end scannner ----------
use std::io::Write;
struct R;
impl PURQ for R {
// d, 角度, x, y, 角度2
type T = (f64, f64, f64, f64, f64);
fn fold(l: &Self::T, r: &Self::T) -> Self::T {
let (a, b, c) = (l.2, l.3, l.4);
let (p, q, r, s, t) = *r;
let rad = c + q;
let mut ans = (l.0, l.1, a, b, c + t + q);
ans.2 += p * rad.cos();
ans.3 += p * rad.sin();
ans.2 += r * rad.cos() - s * rad.sin();
ans.3 += r * rad.sin() + s * rad.cos();
ans
}
fn e() -> Self::T {
(0.0, 0.0, 0.0, 0.0, 0.0)
}
}
fn main() {
let sc = scanner::read_string();
let mut sc = scanner::Scanner::new(&sc);
let out = std::io::stdout();
let mut out = std::io::BufWriter::new(out.lock());
run(&mut sc, &mut out);
}
fn run(sc: &mut scanner::Scanner, out: &mut std::io::BufWriter<std::io::StdoutLock>) {
let n: usize = sc.next();
let q: usize = sc.next();
let mut seg = SegmentTreePURQ::<R>::new(n + 1);
for i in 1..=n {
seg.update_tmp(i, (1.0, 0.0, 0.0, 0.0, 0.0));
}
seg.update_all();
let mut p = vec![(1.0, 0.0); n + 1];
for _ in 0..q {
let op: usize = sc.next();
let k: usize = sc.next();
if op == 0 {
let x: f64 = sc.next();
let d = p[k].0;
let rad = x / 360.0 * std::f64::consts::PI * 2.0;
p[k].1 = rad;
seg.update(k, (d, rad, 0.0, 0.0, 0.0));
} else if op == 1 {
let x: f64 = sc.next();
let rad = p[k].1;
p[k].0 = x;
seg.update(k, (x, rad, 0.0, 0.0, 0.0));
} else {
let p = seg.find(0, k + 1);
let (x, y) = (p.2, p.3);
writeln!(out, "{:.7} {:.7}", x, y).ok();
}
}
}
akakimidori