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;
    }
  • 相关阅读:
    设置标题自适应宽度,动态调整大小
    终止延迟函数
    iOS 关于音频开发
    阻止iOS设备锁屏
    苹果开发——设置iTunes Connect中的Contracts, Tax, and Banking
    【iOS开发必收藏】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!【2012-12-11日更新获取"产品付费数量等于0的问题"】
    uibutton 设置title 居左显示
    通过view 获取viewController
    tableview 自动滑动到某一行
    uibutton 设置圆角边框
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6208754.html
Copyright © 2011-2022 走看看