#line 1 "code.cpp" #define MOD 1000000007LL //#define MOD 998244353LL //#define MOD 18446744069414584321ULL #include #line 1 "cpplib/util/template.hpp" #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") #pragma GCC target("avx") #line 5 "cpplib/util/template.hpp" using namespace std; __attribute__((constructor))void init(){cin.tie(0);ios::sync_with_stdio(false);cout< vec; typedef vector> mat; typedef vector>> mat3; typedef vector svec; typedef vector> smat; templateinline void numout(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<inline void numout2(T t){for(auto i:t)numout(i);} templateinline void output(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<inline void output2(T t){for(auto i:t)output(i);} templateinline void _output(T t){bool f=0;for(lint i=0;iinline void _output2(T t){for(lint i=0;i=lint(a);--i) #define irep(i) for(lint i=0;;++i) inline vector range(long long n){vectorv(n);iota(v.begin(),v.end(),0LL);return v;} inline vector range(long long a,long long b){vectorv(b-a);iota(v.begin(),v.end(),a);return v;} inline vector range(long long a,long long b,long long c){if((b-a+c-1)/c<=0)return vector();vectorv((b-a+c-1)/c);for(int i=0;i<(int)v.size();++i)v[i]=i?v[i-1]+c:a;return v;} templateinline T reversed(T v){reverse(v.begin(),v.end());return v;} #define all(n) begin(n),end(n) #define dist(a,b,c,d) sqrt(pow(a-c,2)+pow(b-d,2)) templatebool chmin(T& s,const E& t){bool res=s>t;s=min(s,t);return res;} templatebool chmax(T& s,const E& t){bool res=s(s,t);return res;} const vector dx={1,0,-1,0,1,1,-1,-1}; const vector dy={0,1,0,-1,1,-1,1,-1}; #define SUM(v) accumulate(all(v),0LL) templateauto make_vector(T x,int arg,Args ...args){if constexpr(sizeof...(args)==0)return vector(arg,x);else return vector(arg,make_vector(x,args...));} #line 6 "code.cpp" //#include "cpplib/math/mod_int.hpp" #line 2 "cpplib/data_structure/segment_tree/segment_tree.hpp" /** * @brief Segment Tree * @docs docs/segment_tree.md * @see https://en.wikipedia.org/wiki/Segment_tree */ #line 1 "cpplib/alga/maybe.hpp" /** * @brief Maybe * @docs docs/maybe.md * @see https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%8A%E3%83%89_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)#Maybe%E3%83%A2%E3%83%8A%E3%83%89 */ template struct maybe{ bool _is_none; T val; maybe():_is_none(true){} maybe(T val):_is_none(false),val(val){} T unwrap()const{ assert(!_is_none); return val; } T unwrap_or(T e)const{ return _is_none?e:val; } bool is_none()const{return _is_none;} bool is_some()const{return !_is_none;} }; template auto expand(F op){ return [op](const maybe& s,const maybe& t){ if(s.is_none())return t; if(t.is_none())return s; return maybe(op(s.unwrap(),t.unwrap())); }; } #line 9 "cpplib/data_structure/segment_tree/segment_tree.hpp" template class segment_tree{ maybe* node; F op; int n=1; public: segment_tree(){} segment_tree(int sz,F op):op(op){ while(n<=sz)n<<=1; node=new maybe[n*2]; for(int i=0;i(); } segment_tree(const vector&v,F op):op(op){ auto f=expand(op); const int sz=v.size(); while(n<=sz)n<<=1; node=new maybe[n*2](); for(int i=0;i(v[i]); for(int i=n-1;i>=1;i--)node[i]=f(node[i*2],node[i*2+1]); } maybe get(int l,int r){ auto f=expand(op); l+=n;r+=n; maybe s,t; while(l>=1;r>>=1; } return f(s,t); } void apply(int t,T _val){ auto f=expand(op); t+=n; maybe val=maybe(_val); while(t){ node[t]=f(node[t],val); t=t>>1; } } void apply_left(int t,T _val){ auto f=expand(op); t+=n; maybe val=maybe(_val); while(t){ node[t]=f(val,node[t]); t=t>>1; } } void change(int t,T val){ auto f=expand(op); t+=n; node[t]=maybe(val); while(t>1){ t=t>>1; node[t]=f(node[t*2],node[t*2+1]); } } }; template segment_tree make_segment_tree(vector v,F op){ return segment_tree(v,op); } template segment_tree make_segment_tree(int size,T goast,F op){ return segment_tree(size,op); } #line 8 "code.cpp" int main(){ lint n,q; cin>>n>>q; auto seg=make_segment_tree(vector>(n,tuple(1.,0.,0.)),[](auto s,auto t){ return make_tuple( get<0>(s)+cos(get<2>(s))*get<0>(t)-sin(get<2>(s))*get<1>(t), get<1>(s)+sin(get<2>(s))*get<0>(t)+cos(get<2>(s))*get<1>(t), get<2>(s)+get<2>(t) ); }); vector>now(n,make_pair(1,0)); rep(i,q){ lint c; cin>>c; if(c==0){ lint s,t; cin>>s>>t; s--; now[s].second=t*M_PIl/180; seg.change(s,make_tuple(now[s].first*cos(now[s].second),now[s].first*sin(now[s].second),now[s].second)); }else if(c==1){ lint s,t; cin>>s>>t; s--; now[s].first=t; seg.change(s,make_tuple(now[s].first*cos(now[s].second),now[s].first*sin(now[s].second),now[s].second)); }else{ lint s; cin>>s; auto tmp=seg.get(0,s).unwrap(); cout<(tmp)<<" "<(tmp)<