zoukankan      html  css  js  c++  java
  • 线段树 poj 2991

    我们只要把这些向量求和,最终所指的位置就是终点,因此我们只要维护好向量的区间和就可以了。对于第二个问题,我们可以用一个数组degree[i]表示第i个向量和第i-1一个向量当前的夹角,这样就有了当前的状态,每次读入操作后就会方便的得到相当于进行旋转多少角度的操作了,然后再更新一下degree[i]即可。并且我们每读入一个操作只会影响一个degree[]的值,不会影响到其他的degree[]。

        总而言之,我们要把每个线段看成一个向量,并维护这些向量的区间和,同时要实现对区间中每个元素都加上一个值这一操作。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    
    using namespace std;
    
    #define MAXN 10010
    const double pi =acos(-1.0);
    int z[MAXN],deg[MAXN],re[MAXN<<3];
    
    struct node
    {
        int l,r;
        double x,y;
    }x[MAXN<<3];
    double getrad(int a)
    {
        return a*pi/180;
    }
    void Build(int l,int r,int a)
    {
        x[a].l=l;
        x[a].r=r;
        x[a].x=0;
        x[a].y=z[r]-z[l-1];
        re[a]=0;
        if(l==r)
            return ;
        int mid=(l+r)>>1;
        Build(l,mid,a<<1);
        Build(mid+1,r,a<<1|1);
    }
    void Rotate(double &dx,double &dy,double rad)
    {
        double  x=dx,y=dy;
        dx=x*cos(rad)-y*sin(rad);
        dy=x*sin(rad)+y*cos(rad);
    }
    void push_down(int a)
    {
        double rad=getrad(re[a]);
        int ls=a<<1,rs=a<<1|1;
        if(re[a])
        {
            re[ls]+=re[a];
            re[rs]+=re[a];
            Rotate(x[ls].x,x[ls].y,rad);
            Rotate(x[rs].x,x[rs].y,rad);
            re[a]=0;
        }
    }
    void push_up(int a)
    {
        x[a].x=x[a<<1].x+x[a<<1|1].x;
        x[a].y=x[a<<1].y+x[a<<1|1].y;
    }
    void update(int l,int r,int a1,int w,int a)
    {
        double rad=getrad(w);
        if(l==r)
        {
            Rotate(x[a].x,x[a].y,rad);
            return ;
        }
        push_down(a);
        int mid=(l+r)>>1;
        if(mid<a1)
            update(mid+1,r,a1,w,a<<1|1);
        else
        {
            update(l,mid,a1,w,a<<1);
            Rotate(x[a<<1|1].x,x[a<<1|1].y,rad);
            re[a<<1|1]+=w;
        }
        push_up(a);
    }
    int main()
    {
        int n,m,ca=1;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            if(ca!=1)
                printf("
    ");
            ca++;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&z[i]);
                z[i]=z[i-1]+z[i];
            }
            memset(deg,0,sizeof(deg));
            Build(1,n,1);
            for(int i=1;i<=m;i++)
            {
                int s,a;
                scanf("%d%d",&s,&a);
                s++;
                a=a-180;
                int delta=a-deg[s];
                deg[s]=a;
                update(1,n,s,delta,1);
                printf("%.2lf %.2lf
    ",x[1].x,x[1].y);
            }
        }
    
        return 0;
    }
  • 相关阅读:
    LevelDB
    Erlang的gen_server的terminate()/2未执行
    集群间心跳检测
    AI从业者关于数学的一些小建议
    《百面机器学习》拾贝----第三章:经典算法
    Demo——Image classification
    《百面机器学习》拾贝----第二章:模型评估
    《百面机器学习》拾贝----第一章:特征工程
    算法工程师---职业生涯规划
    License Plate Detection and Recognition in Unconstrained Scenarios(无约束场景下的车牌检测与识别)
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6208754.html
Copyright © 2011-2022 走看看