poj2991 Crane segment tree

poj2991

Learning solution to a problem

On challenges Programming Contest (white) want to understand Fenwick tree, and find it to talk about the tree line, so he first learning segment tree, so he This question cards for two nights.

The first is the structure of the tree line, a reading generally think of it a little. Here the time of writing, is that the array is large enough to bloom, four times the amount of data is enough.

This question is to segment tree as a carrier, also carries an important vector rotation method. Began to see a direct solution to a problem, look ignorant white equation force, then saw the solution to a problem to know its meaning rad value later, draw a map, you can use differential expansion corners derived, (x, y) clockwise rotated vector angle [alpha] obtained new coordinates (x0, y0) can be x, y, α represents.

Is extremely uncomfortable, debugging, and problem solution has been the second night of the control line by line, suddenly found that after the last update function named cover can be run out of the results, and then lock double rad is the cause of error Shen Mingcheng int rad. Well, after low-level bug check point review of the addition of a data type match.

The code. In fact, it has changed too and solution to a problem is almost the same. But there are some of his comments, it is not the same thing can play the role of a reminder.

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define lson l,mid,rt<<1
#define rson mid,r,rt<<1|1
#define mx 10010

using namespace std;
struct ST
{
    double x,y,lazy;
} T[mx<<2];//开得大一些 直接乘4
const double PI=asin(1.0)*2;
void build(int l,int r,int rt)
{
    T[rt].x=T[rt].lazy=0.0;
    if(r-l==1)
    {
        scanf("%lf",&T[rt].y);
        return ;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    T[rt].y=T[rt<<1].y+T[rt<<1|1].y;
}
double pre[mx];
void update(int L,int R,double rad,int l,int r,int rt)//rad的类型设错一度让我崩溃
{
    double x,y;
    if(L==l && R==r)
    {
        x=T[rt].x*cos(rad) + T[rt].y*sin(rad);
        y=T[rt].y*cos(rad) - T[rt].x*sin(rad);
        T[rt].x=x;T[rt].y=y;//把这部分整体旋转过来
        T[rt].lazy+=rad;//记得lazy值是相加的
        return ;
    }
    int mid=(l+r)>>1;
    if(T[rt].lazy)//让这个区间的左右孩子分别旋转
    {
        x=T[rt<<1].x*cos(T[rt].lazy) + T[rt<<1].y*sin(T[rt].lazy);
        y=T[rt<<1].y*cos(T[rt].lazy) - T[rt<<1].x*sin(T[rt].lazy);
        T[rt<<1].x=x,T[rt<<1].y=y;
        T[rt<<1].lazy+=T[rt].lazy;

        x=T[rt<<1|1].x*cos(T[rt].lazy) + T[rt<<1|1].y*sin(T[rt].lazy);
        y=T[rt<<1|1].y*cos(T[rt].lazy) - T[rt<<1|1].x*sin(T[rt].lazy);
        T[rt<<1|1].x=x,T[rt<<1|1].y=y;
        T[rt<<1|1].lazy+=T[rt].lazy;//要记得把lazy值下放
        T[rt].lazy=0.;
    }
    if(L>=mid) update(L,R,rad,rson);
    else if(R<=mid) update(L,R,rad,lson);
    else
    {
        update(L,mid,rad,lson);
        update(mid,R,rad,rson);
    }
    T[rt].x=T[rt<<1].x+T[rt<<1|1].x;
    T[rt].y=T[rt<<1].y+T[rt<<1|1].y;
}
int main()
{
    int n,c;
    while(~scanf("%d%d",&n,&c))
    {
        build(0,n,1);
        for(int i=1; i<=n; i++)
            pre[i]=PI;
        while(c--)
        {
            int s,a;
            scanf("%d%d",&s,&a);
            double rad=a/180. * PI;
            update(s,n,pre[s]-rad,0,n,1);
            pre[s]=rad;
            printf("%.2lf %.2lf\n",T[1].x,T[1].y);
        }
        cout<<endl;
    }
    return 0;
}

In addition Tucao one poj is really uncomfortable, universal header files can not be used, asin (1.) Are not too, have written asin (1.0), then the situation is ignorant ignorant to force to force the tree fruit, tree poj and ignorant force me.

Guess you like

Origin blog.csdn.net/xuzonghao/article/details/82873601
Recommended