Reprint:: POJ 2991 Segment tree + computational geometry (with C + + structural gymnastics)

Source: Internet
Author: User
Tags cos sin

POJ 2991 Segment tree + computational Geometry(2011-02-27 21:13:44) reproduced
Tags: gossip Category: OI

The question is really disgusting and disgusting, but it does change my view of the line tree, which is a classic topic.

Test instructions: There is a crane consisting of a number of lines of different lengths, starting with a long line starting at (0,0), tail node (0,sum[n]), and the initial value of the angle between each segment is 180 degrees. Then there are some operations A, b to change the angle between section A and a+1 into B-degree, after each operation requires the coordinates of the tail node.

The first thing to do is to use a knowledge of computational geometry (never learned.) Ask for it):

For a vector x, y, the new vector × ', Y ', which is rotated counterclockwise, can be deduced from the following

[x Y]*[cos (a) sin (a)] = [x ' y ']

[-sin (a) cos (a)]

And then a very simple conclusion, after the rotation of a line segment, the angle of the opposite line is not changed, from this point I think it is easy to and the line of the mark of the tree lines together.

The segment tree records the start and end nodes of a segment, and the change angle of the marker's next pass.

This is done for the modification of a line segment:

If the beginning of the segment is exactly equal to the beginning of a node in the first segment tree: The vector is rotated directly from the top node, and the angle is counted into the angle of the marker crossing to mark the segment.

Otherwise, the segment is rotated in the left subtree, then the ends of the right subtree are modified and the right subtree continues to rotate.

Finally, the end coordinates of the right sub-tree of the current node are uploaded.

I think the essence of the problem lies in the Saozi right subtree of the two information of the Union, the left sub-tree modified to affect the right subtree, this topic is the first time encountered.

The code is poorly written and draws on some of the others.

#include <cstdio>
#include <cmath>
#define PI ACOs (-1.0)
#define EPS 1e-8
#define L (x) (x << 1)
#define R (x) ((x << 1) | 1)
#define MAXN 10001

int N, Q;
int LEN[MAXN], SUM[MAXN];
Double mysin[720], mycos[720];

struct POINT
{
Double x, y;

Pointoperator + (const point & A) const
{
Point ret;
Ret.x = x + a.x;
Ret.y = y + a.y;
return ret;
}

Pointoperator-(const point & A) const
{
Point ret;
Ret.x = x-a.x;
Ret.y = Y-A.Y;
return ret;
}
};

struct Segtree
{
int L, r,deg;
Point S,e;
Boolmark;

Intmid ()
{
Return (L + R) >> 1;
}

voidrotate (int angle)
{
Double dx = e.x-s.x, dy = e.y-s.y;
Double newx = dx * mycos[angle +)-dy * mysin[angle +360];
Double newy = DX * mysin[angle +] + dy * mycos[angle +360];
e.x = s.x + newx;
E.y = S.y + newy;
}
} TREE[MAXN * 4];

void Build (int rt, int l, int r)
{
Tree[rt].l =l, TREE[RT].R = R;
tree[rt].deg= 0;
Tree[rt].mark = 0;
tree[rt].s.x= tree[rt].e.x = 0;
tree[rt].s.y= Sum[l]-len[l];
Tree[rt].e.y= Sum[r];
if (l!=r)
{
Build (L (RT), L, Tree[rt].mid ());
Build (R (RT), Tree[rt].mid () + 1, R);
}
}

void Update (int rt)
{
int L =l (rt), R = R (RT);
Propose vectors to rotate according to new nodes
tree[l].deg+= tree[rt].deg;
Tree[l].deg%= 360;
TREE[L].E =tree[l].e-tree[l].s + tree[rt].s;
Tree[l].s =tree[rt].s;
TREE[L]. Rotate (TREE[RT].DEG);

tree[r].e= Tree[r].e-tree[r].s + tree[l].e;
Tree[r].s =TREE[L].E;
tree[r].deg+= tree[rt].deg;
Tree[r].deg%= 360;

TREE[R]. Rotate (TREE[RT].DEG);

Tree[l].mark = Tree[r].mark = 1;
Tree[rt].mark = 0;
tree[rt].deg= 0;
}

int Query (int rt, int order)
{
if (tree[rt].l = = TREE[RT].R) return tree[rt].deg;
Only the leaf nodes are used to record the true angle.
if (Tree[rt].mark) Update (RT);
int LL =l (rt), RR = R (RT);
if (order<= TREE[LL].R) return Query (LL, order);
else Returnquery (RR, order);
}

void change (int rt, int l, int angle)
{
if (tree[rt].l! = TREE[RT].R &&tree[rt].mark) Update (RT);
if (TREE[RT].L = = L)
{
Tree[rt].deg + = angle;
Tree[rt].deg%= 360;
TREE[RT]. Rotate (angle);
Tree[rt].mark = 1;
Return
}
int LL =l (rt), RR = R (RT);
int mid = (tree[rt].l + tree[rt].r) >> 1;
if (l<= mid)
{
Change (LL, l, Angle);
TREE[RR].E = tree[rr].e + tree[ll].e-tree[rr].s;
TREE[RR].S = TREE[LL].E;
Change (RR, mid + 1, angle);
}
Elsechange (RR, L, Angle);
TREE[RT].E =TREE[RR].E;
}

int main ()
{
int cases = 0;
for (int i =-360; i <=; ++i)
{
Mysin[i + n] = sin (i * pi/180);
Mycos[i + n] = cos (i * pi/180);
}
while (~SCANF ("%d%d", &n, &q))
{
if (cases++) puts ("");
Sum[0] = 0;
for (int i = 1; I <= N; ++i)
{
scanf ("%d", Len + i);
Sum[i] = Sum[i-1] + len[i];
}
Build (1, 1, N);

for (int i = 1; I <= Q; ++i)
{
int A, B;
scanf ("%d%d", &a, &b);
b = ((query (1, a)-query (1, a + 1) + + + + B)% 360 + 360)% 360;
Change (1, a + 1, b);
printf ("%.2lf%.2lf\n", Tree[1].e.x + EPS, tree[1].e.y +eps);
}
}
Return0;
}

Reprint:: POJ 2991 Segment tree + computational geometry (with C + + structural gymnastics)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.