• 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;
    }
  • 相关阅读:
    Python——极限编程
    RPC是什么?科普一下
    缓存在高并发场景下的常见问题
    如何提高缓存命中率
    数据库性能优化的误区
    缓存在大型网站架构中的应用
    APP多版本共存,服务端如何兼容?
    水平分库分表的关键问题及解决思路
    分库分表的几种常见玩法及如何解决跨库查询等问题
    分布式系统事务一致性解决方案
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4944890.html
Copyright © 2020-2023  润新知