其他分享
首页 > 其他分享> > POJ-2991 Crane(线段树)

POJ-2991 Crane(线段树)

作者:互联网

题意:给出n条线段,开始时n条线段一词首尾相连,与地面垂直,c次操作,每次操作给出S,A,让线段S_{i}S_{i+1}之间德角度变为A_{i}度,并输出第n条线段的前端坐标。

思路:线段树,区间存储的线段的向量坐标x,y,父亲节点的向量坐标就等于儿子节点的向量坐标相加,在存储一个角度变量,类似于懒惰标记的作用,将一条线段逆时针旋转v度后的坐标为

x1= x0 * cosv - y0 * sinv

y1 = x0 * sinv + y0 * cosv

顺时针:

x1= x0 * cosv + y0 * sinv

y1 = -x0 * sinv + y0 * cosv

#include <math.h>
#include <stdio.h>
#include <string.h>
#define maxn 10005
#define lson num << 1
#define rson num << 1 | 1
const double pi = acos(-1.0);
const double eps = 1e-9;
struct node
{
    int l,r;
    double x,y,add;
}tree[maxn << 2];
double s[maxn],deg[maxn];
void pushdown(int num)
{
    if(fabs(tree[num].add) > eps) {
        tree[lson].add += tree[num].add;
        double tx = tree[lson].x * cos(tree[num].add) + tree[lson].y * sin(tree[num].add);
        double ty = -tree[lson].x * sin(tree[num].add) + tree[lson].y * cos(tree[num].add);
        tree[lson].x = tx;
        tree[lson].y = ty;
        tree[rson].add += tree[num].add;
        tx = tree[rson].x * cos(tree[num].add) + tree[rson].y * sin(tree[num].add);
        ty = -tree[rson].x * sin(tree[num].add) + tree[rson].y * cos(tree[num].add);
        tree[rson].x = tx;
        tree[rson].y = ty;
        tree[num].add = 0.0;
    }
}
void build(int num,int l,int r)
{
    tree[num].l = l;
    tree[num].r = r;
    tree[num].add = 0.0;
    if(l == r) {
        tree[num].x = 0.0;
        tree[num].y = s[r] - s[l - 1];
        return;
    }
    int mid = (l + r) >> 1;
    build(lson,l,mid);
    build(rson,mid + 1,r);
    tree[num].x = 0.0;
    tree[num].y = tree[lson].y + tree[rson].y;
}
void update(int num,int l,int r,double val)
{
    if(tree[num].l == l && tree[num].r == r) {
        tree[num].add += val;
        double tx = tree[num].x * cos(val) + tree[num].y * sin(val);
        double ty = -tree[num].x * sin(val) + tree[num].y * cos(val);
        tree[num].x = tx;
        tree[num].y = ty;
        return;
    }
    pushdown(num);
    int mid = (tree[num].l + tree[num].r) >> 1;
    if(r <= mid)
        update(lson,l,r,val);
    else if(l > mid)
        update(rson,l,r,val);
    else {
        update(lson,l,mid,val);
        update(rson,mid + 1,r,val);
    }
    tree[num].x = tree[lson].x + tree[rson].x;
    tree[num].y = tree[lson].y + tree[rson].y;
}
int main(void)
{
    int n,c,i,id;
    double t,val;
    while(scanf("%d %d",&n,&c) != EOF) {
        for(i = 1; i <= n; i++) {
           scanf("%lf",&t);
            s[i] = s[i - 1] + t;
            deg[i] = 180;
        }
        build(1,1,n);
        while(c--) {
            scanf("%d %lf",&id,&t);
            val = deg[id] - t;
            val /= 180.0;
            val *= pi;
            deg[id] = t;
            update(1,id + 1,n,val);
            if(fabs(tree[1].x) < eps)
                printf("0.00 ");
            else
                printf("%.2f ",tree[1].x);
            if(fabs(tree[1].y) < eps)
                printf("0.00\n");
            else
                printf("%.2f\n",tree[1].y);
        }
    }
    return 0;
}

 

标签:int,2991,rson,tree,add,num,POJ,lson,Crane
来源: https://blog.csdn.net/GYH0730/article/details/90272665