結果
| 問題 |
No.1226 I hate Robot Arms
|
| コンテスト | |
| ユーザー |
so4649
|
| 提出日時 | 2021-01-06 19:49:29 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 1,459 ms / 2,000 ms |
| コード長 | 3,742 bytes |
| コンパイル時間 | 424 ms |
| コンパイル使用メモリ | 82,560 KB |
| 実行使用メモリ | 141,196 KB |
| 最終ジャッジ日時 | 2024-11-07 06:34:04 |
| 合計ジャッジ時間 | 17,279 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 28 |
ソースコード
# セグ木解
class SegmentTree():
def __init__(self, init, unitX, f):
self.f = f # (X, X) -> X
self.unitX = unitX
if type(init) == int:
self.n = init
self.n = 1 << (self.n - 1).bit_length()
self.X = [unitX] * (self.n * 2)
else:
self.n = len(init)
self.n = 1 << (self.n - 1).bit_length()
self.X = [unitX] * self.n + init + [unitX] * (self.n - len(init))
for i in range(self.n-1, 0, -1):
self.X[i] = self.f(self.X[i*2], self.X[i*2|1])
def update(self, i, x):
i += self.n
self.X[i] = x
i >>= 1
while i:
self.X[i] = self.f(self.X[i*2], self.X[i*2|1])
i >>= 1
def getvalue(self, i):
return self.X[i + self.n]
# [l,r)
def getrange(self, l, r):
l += self.n
r += self.n
al = self.unitX
ar = self.unitX
while l < r:
if l & 1:
al = self.f(al, self.X[l])
l += 1
if r & 1:
r -= 1
ar = self.f(self.X[r], ar)
l >>= 1
r >>= 1
return self.f(al, ar)
# Find r s.t. calc(l, ..., r-1) = True and calc(l, ..., r) = False
def max_right(self, l, z):
if l >= self.n: return self.n
l += self.n
s = self.unitX
while 1:
while l % 2 == 0:
l >>= 1
if not z(self.f(s, self.X[l])):
while l < self.n:
l *= 2
if z(self.f(s, self.X[l])):
s = self.f(s, self.X[l])
l += 1
return l - self.n
s = self.f(s, self.X[l])
l += 1
if l & -l == l: break
return self.n
# Find l s.t. calc(l, ..., r-1) = True and calc(l-1, ..., r-1) = False
def min_left(self, r, z):
if r <= 0: return 0
r += self.n
s = self.unitX
while 1:
r -= 1
while r > 1 and r % 2:
r >>= 1
if not z(self.f(self.X[r], s)):
while r < self.n:
r = r * 2 + 1
if z(self.f(self.X[r], s)):
s = self.f(self.X[r], s)
r -= 1
return r + 1 - self.n
s = self.f(self.X[r], s)
if r & -r == r: break
return 0
def debug(self):
print("debug")
print([self.getvalue(i) for i in range(min(self.n, 20))])
from math import cos,sin,atan2,sqrt,radians,pi
n,q = map(int,input().split())
# a = [長さ、直前のアームに対する集合全体の角度、直前のアームに対する集合の最後のアームの向き]
def f(a,b):
l1,arg1,final_arg1 = a
l2,arg2,final_arg2 = b
# クエリがすべて1本目からなのでベクトルaの直前の辺の向きは0とできる
x = l1*cos(arg1)+l2*cos(final_arg1+arg2)
y = l1*sin(arg1)+l2*sin(final_arg1+arg2)
length = sqrt(x**2+y**2)
arg = atan2(y,x)
final_arg = final_arg1+final_arg2
return [length,arg,final_arg]
seg = SegmentTree([[1,0,0] for i in range(n)],[0,0,0],f)
l = [1]*n
for _ in range(q):
query = list(map(int,input().split()))
if query[0] == 0:
i,x = query[1:]
seg.update(i-1,[l[i-1],radians(x),radians(x)])
elif query[0] == 1:
i,x = query[1:]
length,arg,final_arg = seg.getvalue(i-1)
seg.update(i-1,[x,arg,final_arg])
l[i-1] = x
else:
i = query[1]
length,arg,final_arg = seg.getrange(0,i)
print(length*cos(arg),length*sin(arg))
so4649