zoukankan      html  css  js  c++  java
  • POJ 2991 Crane

    二次联通门 : POJ 2991 Crane

    /*
        POJ 2991 Crane 
        
        线段树维护向量
        对于每次修改操作
        修改x的角度 
        就是修改x~N区间的所有向量
        
        打个标记记录角度
        
        当前向量的计算式子为
        res为度数 
        x = tree[now].x * cos (res) - tree[now].y * sin (res);
        y = tree[now].x * sin (res) + tree[now].y * cos (res);
        
        注意弧度制与角度值的互换
        
        注意还要记录一下上次该向量的角度, 即angle[i] 
         
        每次修改的角度就是x - angle[pos] x是给定的角, pos是修改的位置 
         
        查询的话就是第一个点的向量。。。
        
        MMP竟然有负角。。。
        我的读入优化没判负数导致WA了半天。。。 
    */
    #include <cstdio>
    #include <cmath>
    
    #define Max 1000001
    
    inline void read (int &now)
    {
        now = 0;
        register char word = getchar ();
        bool temp = false;
        while (word < '0' || word > '9')
        {
            if (word == '-')
                temp = true;
            word = getchar ();
        }
        while (word >= '0' && word <= '9')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
        if (temp)
            now = -now;
    }
    
    int N, M;
    
    double angle[Max];
    
    class Segment_Tree_Type
    {
        
        private :
            
            
            struct Segment_Tree_Date
            {
                int l;
                int r;
                int Mid;
                double x;
                double y;
                double Flandre;
                
            }
            tree[Max];
            
            inline void Rotate (int now, int angle)
            {
                double res = (double)angle * acos (-1.0) / 180.0;
                double x = tree[now].x * cos (res) - tree[now].y * sin (res);
                double y = tree[now].x * sin (res) + tree[now].y * cos (res);
                tree[now].x = x;
                tree[now].y = y;
            }
            
        public :
            
            void Build (int l, int r, int now)
            {
                tree[now].l = l;
                tree[now].r = r;
                tree[now].Flandre = 0;
                if (l == r)
                {
                    scanf ("%lf", &tree[now].y);
                    tree[now].x = 0;
                    tree[now].Flandre = 0;
                    return ;
                }
                tree[now].Mid = l + r >> 1;
                Build (l, tree[now].Mid, now << 1);
                Build (tree[now].Mid + 1, r, now << 1 | 1);
                tree[now].x = tree[now << 1].x + tree[now << 1 | 1].x;
                tree[now].y = tree[now << 1].y + tree[now << 1 | 1].y;
            }
        
            void Change_section (int l, int r, int now, int to)
            {
                if (tree[now].l == l && tree[now].r == r)
                {
                    tree[now].Flandre += to;
                    Rotate (now, to);
                    return ;
                }
                if (tree[now].Flandre)
                {
                    tree[now << 1].Flandre += tree[now].Flandre;
                    tree[now << 1 | 1].Flandre += tree[now].Flandre;
                    Rotate ((now << 1), tree[now].Flandre);
                    Rotate ((now << 1 | 1), tree[now].Flandre);
                    tree[now].Flandre = 0;
                }
                if (r <= tree[now].Mid)
                    Change_section (l, r, now << 1, to);
                else if (l > tree[now].Mid)
                    Change_section (l, r, now << 1 |1, to);
                else 
                {
                    Change_section (l, tree[now].Mid, now << 1, to);
                    Change_section (tree[now].Mid + 1, r, now << 1 | 1, to);
                }
                tree[now].x = tree[now << 1].x + tree[now << 1 | 1].x;
                tree[now].y = tree[now << 1].y + tree[now << 1 | 1].y;
            }
            
            inline double Query_x ()
            {
                return tree[1].x;
            }
            
            inline double Query_y ()
            {
                return tree[1].y;
            }
            
            void Prepare ()
            {
                for (int i = 1; i <= Max; i++)
                    angle[i] = 180.0;
            }
    };
    
    Segment_Tree_Type Tree;
    
    
    int main (int argc, char *argv[])
    {
        int x, y;
        for (; scanf ("%d%d", &N, &M) == 2; )
        {
            Tree.Build (1, N, 1); 
            Tree.Prepare (); 
            for (; M--; )
            {
                read (x);
                read (y);
                Tree.Change_section (x + 1, N, 1, y - angle[x]); 
                printf ("%.2lf %.2lf
    ", Tree.Query_x (), Tree.Query_y ());
                angle[x] = (double)y;
            }
        }
        return 0;
    }
  • 相关阅读:
    Reactive(1) 从响应式编程到"好莱坞"
    [动图演示]Redis 持久化 RDB/AOF 详解与实践
    补习系列(22)-全面解读 Spring Profile 的用法
    Android手机打造你的Python&Java开发工具!
    人工神经网络模型种类
    最小二乘拟合
    LDA主体模型
    Logistic Regression求解classification问题
    batch gradient descent(批量梯度下降) 和 stochastic gradient descent(随机梯度下降)
    SVM实验
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/6910546.html
Copyright © 2011-2022 走看看