POJ 2991 Crane (线段树)

来源:互联网 发布:js执行href跳转action 编辑:程序博客网 时间:2024/05/24 16:17

关键点:向量(a,b)逆时针旋转p度后为(acosp-bsinp,asinp+bcosp)

每段看成一个向量,最后结果为向量和。

这样记录每段向量的两个值,和与y轴的夹角。

prv[i]表示i和i+1的夹角。


代码:

#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#include<cmath>#include<cstdlib>#define lson l ,m ,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const double eps = 1e-8;const double PI = acos(-1.0);const int maxn = 20005;int n,q,L[maxn];struct SegTree{    double vx[maxn<<2],vy[maxn<<2],ang[maxn<<2],prv[maxn];    void init(){        for(int i=0;i<maxn;i++) prv[i] = PI;    }    void modify(int rt){        double s = sin(ang[rt]),c = cos(ang[rt]);        double x = vx[rt], y = vy[rt];        vx[rt] = c*x - s*y;        vy[rt] = s*x + c*y;        ang[rt] = 0;    }    void push_up(int rt){        vx[rt] = vx[rt<<1] + vx[rt<<1|1];        vy[rt] = vy[rt<<1] + vy[rt<<1|1];    }    void push_down(int l,int r,int rt){        if(fabs(ang[rt]) < eps) return;        if(l != r){            ang[rt<<1] += ang[rt];            ang[rt<<1|1] += ang[rt];        }        modify(rt);    }    void build(int l,int r,int rt){        ang[rt] = vx[rt] = 0;        if(l == r){            vy[rt] = L[l];            return;        }        int m = (l + r) >> 1;        build(lson);build(rson);        push_up(rt);    }    void update(int a,int b,double x,int l,int r,int rt){        push_down(l,r,rt);        if(l > b || r < a) return;        if(a <= l && r <= b){            ang[rt] = x;            push_down(l,r,rt);            return;        }        int m = (l + r) >> 1;        update(a,b,x,lson);update(a,b,x,rson);        push_up(rt);    }    void debug(int l,int r,int rt){        push_down(l,r,rt);        if(l == r){            printf("%.2f %.2f\n",vx[rt],vy[rt]);            return;        }        int m = (l + r) >> 1;        debug(lson);debug(rson);    }}sol;int main(){    int cas = 0;    while(~scanf("%d%d",&n,&q)){        if(cas++) putchar('\n');        for(int i=1;i<=n;i++) scanf("%d",&L[i]);        sol.init();sol.build(1,n,1);        int s,v;        while(q--){            scanf("%d%d",&s,&v);            double ang = 1.0*v/180*PI;            sol.update(s+1,n,ang-sol.prv[s],1,n,1);            sol.prv[s] = ang;            //sol.debug(1,n,1);putchar('\n');            printf("%.2f %.2f\n",sol.vx[1],sol.vy[1]);        }    }    return 0;}


0 0