Description
There are n first-hand levers on a plane. All initial levers are 1 units in length. First Lever left
The side is located at (0,0). All levers are placed horizontally.
Now I'm going to do the following two operations on these levers:
1. Stretching
This operation is labeled 1, which means that a lever is placed along the original to elongate x units.
2. Rotate
This label operation is 2, which means to extend a lever counterclockwise x degrees.
Now, my concern is where is the right side of the nth lever after each operation?
Input
The first line of two integers n,m represents the number of levers and operands.
The next few lines, each line of three x, Y, Z.
If X=1, indicates a Z-unit of the lever of the Y-root.
If x=2, indicates the z-clockwise rotation of the y lever
Output
For each operation, output a coordinate of x, y representing the position of the right of the nth lever. Accurate to 6 decimal places.
Sample Input
5 4
1 1 3
2 3 90
2 5 48
1 4 1
Sample Output
8.000000 0.000000
5.000000-3.000000
4.256855-2.669131
4.256855-3.669131
Hint
30% data available n,m<=100
60% data available n,m<=2000
100% Data Guarantee n,m<=300000 1<=x<=2 1<=y<=n 1<=z<=359
There is a row of small sticks horizontally placed, there are two operations, 1: Single point to modify the length of 1 small sticks, 2: Modify the angle of rotation of a stick.
Maintain a small stick at each end of the point, respectively, with the angle of x angle, because angle can be directly added and minus, and then each operation to output the last one of the horizontal axis, then we can maintain a fulcrum relative to the previous fulcrum of the DX value, then the last point is Sigma ( DX), then simply maintain Sigma (DX)-->sx Well, sy the same.
One point modifies the len of a stick, then the sx of that point = cos (angle/180*pi) *len,sy = sin (angle/180*pi) *len.
Rotate a stick, then all the sticks and the x-axis angle will increase, that is, the angle of the interval modification.
We know sx = cos (A1) *l1 + cos (a2) *l2 + cos (a3) *l3 + ... cos (an) *ln,sy = sin (A1) *l1 + sin (A2) *l2 + sin (A3) *l3 + ... sin (an) *ln
Increase the angle of f
SX = cos (a1+f) *l1 + cos (a2+f) *l2 + cos (a3+f) *l3 + ... cos (an+f) *ln
Turn cosine on, sx = cos (f) * (cos (a1) *l1 + cos (a2) *l2 + cos (a3) *l3 + ... cos (an) *ln)-sin (f) * (sin (A1) *l1 + sin (A2) *l2 + sin (A3) *l3 +: . Sin (an) *ln)
So, sx = cos (f) *sx-sin (f) *sy
In the same vein, sy = cos (f) *sx + sin (f) *sy
Then we need to maintain the value of SX (Sigma (DX)), Sy (Sigma (DY)), each with an x-axis angle, the length of each stick, the interval to modify the angle of the lazy mark.
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include < algorithm>using namespace Std;const int N = 300010;const double pi = ACOs ( -1.0); struct node{double angle,sx,sy,sl,rk;} tree[n<<2]; #define Lson k<<1,l,mid#define rson k<<1|1,mid+1,rvoid pushup (int k) {tree[k].sx = Tree[k <<1].sx+tree[k<<1|1].sx;tree[k].sy = Tree[k<<1].sy+tree[k<<1|1].sy;} void Processdown (int k) {double sx,sy;double &res = tree[k].rk;if (res = = 0) return;sx = Tree[k<<1].sx;sy = tree[k& Lt;<1].sy;tree[k<<1].rk + = res;tree[k<<1].sx = cos (tree[k<<1].rk/180.0*pi) *sx-sin (tree[k< <1].RK/180.0*PI) *sy;tree[k<<1].sy = sin (tree[k<<1].rk/180.0*pi) *sx+cos (tree[k<<1].rk/180.0* PI) *sy;sx = Tree[k<<1|1].sx;sy = Tree[k<<1|1].sy;tree[k<<1|1].rk + = res;tree[k<<1|1].sx = cos ( TREE[K<<1|1].RK/180.0*PI) *sx-sin (tree[k<<1|1].rk/180.0*pi) *sy;tree[k<<1|1].sy =Sin (tree[k<<1|1].rk/180.0*pi) *sx+cos (tree[k<<1|1].rk/180.0*pi) *sy;res = 0;} void build (int k,int l,int R) {if (L = = r) {tree[k].sx = TREE[K].SL = 1;tree[k].sy = Tree[k].angle = 0;return;} Processdown (k); int mid = (l+r) >>1;build (Lson); build (Rson);p ushup (k);} void Updatelen (int k,int l,int r,int x,double value) {if (L = = r) {TREE[K].SL + = Value;tree[k].angle + = Tree[k].rk;tree[k].rk = 0;tree[k].sx = cos (tree[k].angle/180.0*pi) *tree[k].sl;tree[k].sy = sin (tree[k].angle/180.0*pi) *tree[k].sl;return;} Processdown (k); int mid = (l+r) >>1;if (x <= mid) Updatelen (lson,x,value); else if (x > Mid) Updatelen (Rson,x, Value);p ushup (k);} void Updateangle (int k,int l,int r,int ql,int qr,double value) {if (L = = QL && r = = qr) {tree[k].rk-= value;double s x = Tree[k].sx,sy = tree[k].sy;tree[k].sx = cos (-value/180.0*pi) *sx-sin (-value/180.0*pi) *sy;tree[k].sy = sin (-value/ 180.0*PI) *sx+cos (-VALUE/180.0*PI) *sy;return;} Processdown (k); int mid = (l+r) >>1;if (QR <= mid) Updateangle (LSON,QL, Qr,value), else if (QL > Mid) Updateangle (Rson,ql,qr,value), Else Updateangle (Lson,ql,mid,value), Updateangle (Rson, Mid+1,qr,value);p Ushup (k);} int main () {freopen ("stick.in", "R", stdin), Freopen ("Stick.out", "w", stdout);d ouble x;int n,m,flag,id;ios::sync_with_ Stdio (false); Cin>>n>>m;build (1,1,n); while (m--) {cin>>flag>>id>>x;if (flag = = 1) { Updatelen (1,1,n,id,x);} if (flag = = 2) {updateangle (1,1,n,id,n,x);} printf ("%.6lf%.6lf\n", tree[1].sx,tree[1].sy);} return 0;}
Pivot rotation (self-creation & line tree)-Xgtao-