#pragma GCC optimize("Ofast") #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long int ll; typedef unsigned long long ull; mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); ll myRand(ll B) { return (ull)rng() % B; } inline double time() { return static_cast(chrono::duration_cast(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9; } struct point{ long double x,y; point() {} point(long double x,long double y): x(x), y(y) {} point& operator-=(const point &p){ x -= p.x; y -= p.y; return *this; } point& operator+=(const point &p){ x += p.x; y += p.y; return *this; } point& operator*=(long double d){ x *= d; y *= d; return *this; } point& operator/=(long double d){ x /= d; y /= d; return *this; } const point operator+ (const point& p) const; const point operator- (const point& p) const; const point operator* (long double d) const; const point operator/ (long double d) const; }; const point point::operator+ (const point& p) const{ point res(*this); return res += p; } const point point::operator- (const point& p) const{ point res(*this); return res -= p; } const point point::operator* (long double d) const{ point res(*this); return res *= d; } const point point::operator/ (long double d) const{ point res(*this); return res /= d; } long double abs(point P){ return sqrt(P.x*P.x+P.y*P.y); } template struct segtree { int n; vector tree; segtree() : segtree(0) {} segtree(int n) : n(n), tree(vector(n<<1, e())) {} void update(int k) { tree[k] = op(tree[k<<1|0], tree[k<<1|1]); } S operator[](int i) {return tree[i+n]; } void set(int i, S x) { i += n; tree[i] = x; while(i >>= 1) { update(i); } } // [l,r) S query(int l, int r) { S sml = e(), smr = e(); for(l += n, r += n; l < r; l >>= 1, r >>= 1){ if(l & 1) sml = op(sml, tree[l++]); if(r & 1) smr = op(tree[--r], smr); } return op(sml,smr); } }; // ベクトルと回転角度を持つ using P = pair; P op(P a,P b){ auto p = a.first; auto pp = b.first; p += point(pp.x*cos(a.second)-pp.y*sin(a.second), pp.x*sin(a.second)+pp.y*cos(a.second)); return {p, a.second+b.second}; } P e() {return {{0,0},0};}; int main(){ cin.tie(nullptr); ios::sync_with_stdio(false); int n,q; cin >> n >> q; segtree seg(n); for(int i=0;i> type; int i; cin >> i; i--; auto P = seg[i]; auto &p = P.first; if(type == 1){ int w; cin >> w; p = p / abs(p) * w; seg.set(i, P); } else if(type == 0){ int w; cin >> w; long double theta = acos(-1.0L) * (w) / 180.0; p = {p.x*cos(-P.second+theta)-p.y*sin(-P.second+theta), p.x*sin(-P.second+theta)+p.y*cos(-P.second+theta)}; P.second = theta; seg.set(i, P); } else{ auto res = seg.query(0, i+1); double x = res.first.x, y = res.first.y; printf("%.9f %.9f\n",x, y); } } }