Main topic:
Give a piece of rope that is formed by a line of n the section I segment (starting from 1) is a point Pi-1 and the point Pi is connected, the beginning of the rope from the origin to the Y axis of the positive direction of extension, and now to do m modification of the rope, each modification will be the first and 1 line segments adjusted to the position of the section U-bar counterclockwise direction w degrees, The relationship between the other segments is constant, requiring the output of the dot PN coordinates after each modification.
Input: The first line n,m (N,m <= 10000); the second row N integers, representing the length of these segments (the length is an integer between 1~99), and the next M line two integers per line u,w (0 < U < n,0 <= W < 360).
Output: For each modification of the output line, contains two two-bit decimals, representing the coordinates of the point PN.
Analysis:
It can be observed that when the section K segment rotates x degrees and the angle relationship between other segments is constant, the K + 1 ~ N segment does not change with respect to the section K segment, and the X-degree is rotated relative to the planar Cartesian coordinate system, and in the K + 1 ~ N segment, The shape of any number of segments is changed before and after modification, and the X-degree is rotated relative to the modification! All segments are represented by vector (x, y), then each operation is to rotate the K ~ n segment, and then output the and of the vectors represented by all the segments.
Because N,m <= 10000, it is obvious to think with Nlogn approach, and through the above analysis, then this problem is converted to the interval and interval of the sum, modification will be troublesome, because different line changes are not the same, but there is a common point is the angle of rotation, with a line tree to maintain, It's good to record the angle in the Lazy-tag. The x, y of each node of the segment tree represents all the vectors of the interval represented by that node and can also be seen as a vector.
(In fact, the time limit for this problem is that 2s,n^2 violence can be done, and all the sin and cos need to be preprocessed.) )
The error that occurred:
1, accuracy error: Although only let the output two decimal places, but still will appear the accuracy error, the reason of the error is that PI,PI is equal to ACOs (-1) and cannot be entered manually. (The seniors are planted here.) )
2, Angle calculation: Call Atan (x, y) to calculate the angle of the vector (x, y) and the axis, the x, y need to be positive and negative judgment. (One day before the tune out Qaq)
Code:
1#include <cstdio>2#include <cmath>3 using namespacestd;4 Const DoublePI = ACOs (-1);5 structTree {6 Doublex, y, lazy;7} t[1000000];8 intN, M, U, W, len[10010];9 DoubleDegree (DoubleOxDoubleOy) {Ten returnAtan (Ox/oy) + (Oy <0? Pi:0); One } A DoubleTurn (DoubleDegDouble&ox,Double&Oy) { - Doubletx = Ox * COS (DEG)-Oy *sin (deg); - Doublety = ox * sin (deg) + Oy *cos (deg); theOx = tx, Oy =Ty; - } -InlinevoidPushup (into) { -t[o].x = T[o <<1].x + t[o <<1|1].x; +T[O].Y = T[o <<1].y + t[o <<1|1].y; - } +InlinevoidPushdown (into) { A intL = o <<1, r = o <<1|1; at Doubledeg =T[o].lazy; -Turn (deg, t[l].x, t[l].y); T[l].lazy + =deg; -Turn (deg, t[r].x, t[r].y); T[r].lazy + =deg; -T[o].lazy =0; - } - voidBuild (intIintLeftintRight ) { in if(Left <Right ) { - intMid = (left + right) >>1; toBuild (I <<1, left, mid); +Build (I <<1|1, Mid +1, right); - pushup (i); the}Elset[i].x =0, t[i].y =Len[left]; * } $ intMleft, mright;Panax Notoginseng Doublemdeg, MX, my; - voidModify (intIintLintRintmid) { the if(Mleft <= l && mright >=r) { + Turn (mdeg, t[i].x, t[i].y); AT[i].lazy + = mdeg;return; the } + pushdown (i); - if(Mleft <= mid && mright >=l) $Modify (I <<1, L, Mid, (L + mid) >>1); $ if(Mright > Mid && mleft <=R) -Modify (I <<1|1, Mid +1, R, (R + mid +1) >>1); - pushup (i); the } - voidMturn (intLeftintRightDoubledeg) {WuyiMleft = left, mright = right; Mdeg =deg; theModify (1,1, N, (1+ N) >>1); - } Wu voidAsk (intIintLintRintmid) { - if(Mleft <= l && mright >=r) { Aboutmx + = t[i].x, my + =t[i].y; $ return; - } - pushdown (i); - if(Mright >= l && mleft <=mid) AAsk (I <<1, L, Mid, (L + mid) >>1); + if(Mleft <= r && mright >mid) theAsk (I <<1|1, Mid +1, R, (R + mid +1) >>1); - } $ voidAskxy (intLeftintRight ) { theMleft = left, mright = right; MX = my =0; theAsk (1,1, N, (1+ N) >>1); the if(ABS (MX) <=0.001) MX =0; the ifABS (MY) <=0.001) My =0; - } in intMain () { thescanf ("%d%d", &n, &m); the for(inti =1; I <= N; i++) Aboutscanf ("%d", &len[i]); theBuild (1,1, n); the for(inti =0; I < m; i++) { thescanf ("%d%d", &u, &W); + askxy (U, u); - Doubledeg =degree (mx, my); theAskxy (U +1, U +1);Bayideg = pi * w/ the-(deg + pi-degree (mx, my)); theMturn (U +1, n, deg); theAskxy (1, n); -printf ("%.2LF%.2lf\n", MX, my); - } the}
Source: Training Questions from seniors
Splicing games (segment tree, computational geometry)