zoukankan      html  css  js  c++  java
  • POJ 2991 Crane(线段树)

    很自然会想到是线段树,需要考虑维护什么信息。

    我们需要的答案是从原点到末端的坐标,这个信息可以看出是多个向量相加,所以我们在子区间维护左端点到右端点的一个向量。

    因为角度会发生改变,那么再维护一个左右区间之间的角度。那么父节点的向量就等于左孩子的向量加上右孩子旋转以后的向量。

    对于修改si和si+1之间的角度,对于以上的信息,相当于si+1以后所有角度都增加了。因此只要修改增量就好了。

    此外,线段树最大深度的科学估计方法:max_deep = ceil(log2(maxn))+1),而且2^(max_deep ) ≤4*maxn,是一个更紧的上界,对于主席树也适用。

    #include<cstdio>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    typedef long long ll;
    
    #define para int o = 1, int l = 0,int r = n-1
    #define lo (o<<1)
    #define ro (o<<1|1)
    #define TEMPvar int mid = (l+r)>>1, lc = lo, rc = ro;
    #define lsn lc, l, mid
    #define rsn rc, mid+1, r
    
    const int maxn = 1e4+5, ST_SIZE = 1<<15;//((int)ceil(log2(maxn))+1);//4*N , 0base -1
    const double PI = acos(-1);
    double rad[ST_SIZE];
    double vx[ST_SIZE], vy[ST_SIZE];
    int L[maxn];
    int n;
    double prv[maxn];
    
    void build(para)
    {
        rad[o] = vx[o] = 0;
        if(r == l){
            vy[o] = L[l];
        }
        else {
            TEMPvar
            build(lsn);
            build(rsn);
            vy[o] = vy[lc] + vy[rc];
        }
    }
    
    int qs;
    double qDrad;
    void update(para)
    {
        if(l < r){
            TEMPvar
            if(qs<=mid) {
                update(lsn);
                rad[o] += qDrad;
            }
            else update(rsn);
    
            double s = sin(rad[o]), c = cos(rad[o]);
            vx[o] = vx[lc] + c*vx[rc] - s*vy[rc];
            vy[o] = vy[lc] + s*vx[rc] + c*vy[rc];
        }
    }
    
    //#define LOCAL
    int main()
    {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif
        int C;
        bool firstCase = true;
        while(~scanf("%d%d",&n,&C)){
            if(!firstCase) puts("");
            else firstCase = false;
            for(int i = 0; i < n; i++) scanf("%d", L+i);
            fill(prv,prv+n-1,PI);
            build();
            while(C--){
                double ang;
                scanf("%d %lf", &qs, &ang);
                ang = ang/180*PI;
                qDrad = ang-prv[--qs];
                update();
                prv[qs] = ang;
                printf("%.2f %.2f
    ", vx[1], vy[1]);
            }
        }
        return 0;
    }
  • 相关阅读:
    获取SqlServer2005表结构
    SQL SERVER 2005连接其它数据库并导入数据表
    vs2008安装失败问题
    Elmah使用方法
    使用postman发送请求,body为空
    docker的简单使用
    mongodb5最新版本的安装和向外暴露端口
    初探gin框架
    img图片的src指定为网络中随便找的图片链接,但是控制台报错get请求403
    父元素为flex布局时,设置最后一个子元素靠右,其他靠左
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4944890.html
Copyright © 2011-2022 走看看