結果
| 問題 |
No.1226 I hate Robot Arms
|
| ユーザー |
|
| 提出日時 | 2020-09-11 22:31:43 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 5,699 bytes |
| コンパイル時間 | 3,000 ms |
| コンパイル使用メモリ | 228,712 KB |
| 最終ジャッジ日時 | 2025-01-14 10:50:50 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | WA * 4 TLE * 24 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1);
template<typename T>
struct BIT {
int n;
vector<T> dat;
BIT(int n=0){
initialize(n);
}
void initialize(int nin){
n = nin;
dat.assign(n, 0);
}
T sum(int i){
T s = 0;
while(i >= 0){
s += dat[i];
i = (i & (i+1)) - 1;
}
return s;
}
T sum_between(int i, int j){
return sum(j) - sum(i-1);
}
void plus(int i, T x){
while(i < n){
dat[i] += x;
i |= i+1;
}
}
// a[0]+...+a[ret] >= x
int lower_bound(T x){
if(x < 0) return -1;
int ret = -1;
int k = 1;
while(2*k <= n) k <<= 1;
for( ;k>0; k>>=1){
if(ret+k < n && dat[ret+k] < x){
x -= dat[ret+k];
ret += k;
}
}
return ret + 1;
}
};
template<typename F, typename T, typename Func_mf, typename Func_op, typename Func_mv>
struct LazySegtree {
int n, n_org;
vector<T> dat;
vector<F> laz;
Func_mf merge_functions;
Func_op operate;
Func_mv merge_values;
F fe;
T te;
LazySegtree(){}
LazySegtree(int n_org,
Func_mf merge_functions,
Func_op operate,
Func_mv merge_values,
F fe, T te):
n_org(n_org),
merge_functions(merge_functions),
operate(operate),
merge_values(merge_values),
fe(fe), te(te){
n = 1;
while(n < n_org) n <<= 1;
dat.assign(2*n-1, te);
laz.assign(2*n-1, fe);
}
void build(vector<T>& A){
for(int k=0; k<int(A.size()); k++) dat[k+n-1] = A[k];
for(int k=n-2; k>=0; k--) dat[k] = merge_values(dat[2*k+1], dat[2*k+2]);
}
void eval(int k, int w){
if(laz[k] == fe) return;
operate(dat[k], laz[k], w);
if(k < n-1){
merge_functions(laz[2*k+1], laz[k]);
merge_functions(laz[2*k+2], laz[k]);
}
laz[k] = fe;
}
void update_between(int a, int b, F x){
update(a, b+1, x, 0, 0, n);
}
void update(int a, int b, F x, int k, int lb, int rb){
eval(k, rb-lb);
if(b <= lb || rb <= a) return;
if(a <= lb && rb <= b){
merge_functions(laz[k], x);
eval(k, rb-lb);
}else{
int mb = (lb+rb)>>1;
update(a, b, x, 2*k+1, lb, mb);
update(a, b, x, 2*k+2, mb, rb);
dat[k] = merge_values(dat[2*k+1], dat[2*k+2]);
}
}
T get_between(int a, int b){
return query(a, b+1, 0, 0, n);
}
T query(int a, int b, int k, int lb, int rb){
eval(k, rb-lb);
if(rb<=a || b<=lb) return te;
if(a<=lb && rb<=b) return dat[k];
int mb = (lb+rb)>>1;
T vl = query(a, b, 2*k+1, lb, mb);
T vr = query(a, b, 2*k+2, mb, rb);
return merge_values(vl, vr);
}
};
typedef vector<vector<double>> Mat;
Mat matmul(Mat A, Mat B){
assert(A[0].size() == B.size());
int N = A.size(), M = B[0].size(), K = B.size();
Mat ans(N, vector<double>(M));
for(int i=0; i<N; i++) for(int j=0; j<M; j++) for(int k=0; k<K; k++) ans[i][j] += A[i][k] * B[k][j];
return ans;
}
Mat matadd(Mat A, Mat B){
int N = A.size(), M = A[0].size();
for(int i=0; i<N; i++) for(int j=0; j<M; j++) A[i][j] += B[i][j];
return A;
}
Mat E22 = {{1.0, 0.0}, {0.0, 1,0}};
Mat Z21 = {{0.0}, {0.0}};
auto make_segtree = [](int N){
using F = pair<Mat, Mat>;
using T = Mat;
auto merge_functions = [](F& f, F& g){
f.first = matmul(g.first, f.first);
f.second = matadd(matmul(g.first, f.second), g.second);
};
auto operate = [](T& v, F& f, int w){
v = matadd(matmul(f.first, v), f.second);
};
auto merge_values = [](T& a, T& b){
return a == Z21 ? b : a;
};
F fe = {E22, Z21};
T te = Z21;
return LazySegtree<F, T, decltype(merge_functions), decltype(operate), decltype(merge_values)>
(N, merge_functions, operate, merge_values, fe, te);
};
int main(){
int N, Q;
cin >> N >> Q;
auto st = make_segtree(N+1);
vector<int> L(N, 1);
BIT<int> Theta(N);
auto calc = [&](int deg, Mat pos)->pair<Mat, Mat>{
double theta = deg*PI/180;
double x0 = pos[0][0], y0 = pos[1][0];
Mat a = {{cos(theta), -sin(theta)}, {sin(theta), cos(theta)}};
Mat b = {
{-cos(theta)*x0 + sin(theta)*y0 + x0},
{-sin(theta)*x0 - cos(theta)*y0 + y0}
};
return {a, b};
};
vector<Mat> ini(N+1);
for(int i=0; i<=N; i++) ini[i] = {{double(i)}, {0.0}};
st.build(ini);
while(Q--){
int t;
cin >> t;
if(t == 1){
int i, x;
cin >> i >> x;
i--;
int d = x - L[i];
int theta = Theta.sum(i) % 360;
Mat diff = {{d*cos(theta*PI/180)}, {d*sin(theta*PI/180)}};
st.update_between(i+1, N, {E22, diff});
L[i] = x;
}else if(t == 0){
int i, x;
cin >> i >> x;
i--;
auto pos = st.get_between(i, i);
int diff = x - Theta.sum_between(i, i);
auto f = calc(x, pos);
st.update_between(i+1, N, f);
Theta.plus(i, diff);
}else{
int i;
cin >> i;
auto ans = st.get_between(i, i);
cout << fixed << setprecision(10) << ans[0][0] << " " << ans[1][0] << endl;
}
}
return 0;
}