• (WA)BZOJ 4821: [Sdoi2017]相关分析


    二次联通门 : BZOJ 4821: [Sdoi2017]相关分析

     2017.8.23 Updata

    妈妈!!这道题卡我!!!就是不然我过!!!!!

    #include <cstdio>
    #include <iostream>
    
    const int BUF = 12312312;
    char Buf[BUF], *buf = Buf;
    
    inline void read (int &now)
    {
        bool temp = false;
        for (now = 0; !isdigit (*buf); ++ buf)
            if (*buf == '-')  temp = true;
        for (; isdigit (*buf); now = now * 10 + *buf - '0', ++ buf);
        if (temp) now = -now;
    }
    
    #define Max 100050
    double _x[Max], _y[Max];
    double i2[Max], _i[Max];
    
    struct S_D 
    {
        S_D *Left, *Right;
        double x, x2, y, xy, ss, st, ts, tt;
        int l, r, Mid;
        bool tag;
        
        S_D (int _l, int _r)
        {
            x = x2 = ss = st = ts = tt = y = xy = 0;
            Left = Right = NULL;
            l = _l, r = _r, Mid = l + r >> 1;
            tag = false;
        }
    
        inline void Up ()
        {
            x = Left->x + Right->x, xy = Left->xy + Right->xy;
            y = Left->y + Right->y;
            x2 = Left->x2 + Right->x2;
        }
    
        inline void Down ()
        {
            S_D *L = Left, *R = Right;
        
            double ls = L->r - L->l + 1, rs = R->r - R->l + 1;
            if (tag)
            {
                L->x = ts * ls + _i[L->r] - _i[L->l - 1];
                   L->y = tt * ls + _i[L->r] - _i[L->l - 1];    
                L->xy = ts * tt * ls + (_i[L->r] - _i[L->l - 1]) * (ts + tt) + i2[L->r] - i2[L->l - 1];
                L->x2 = ts * ts * ls + (_i[L->r] - _i[L->l - 1]) * ts * 2.0 + i2[L->r] - i2[L->l - 1];
                
                
                R->x = ts * rs + _i[R->r] - _i[R->l - 1];
                R->y = tt * rs + _i[R->r] - _i[R->l - 1];
                R->xy = ts * tt * rs + (_i[R->r] - _i[R->l - 1]) * (ts + tt) + i2[R->r] - i2[R->l - 1];
                R->x2 = ts * ts * rs + (_i[R->r] - _i[R->l - 1]) * ts * 2.0 + i2[R->r] - i2[R->l - 1];
                L->ts = R->ts = ts, L->tt = R->tt = tt;
                L->ss = R->st = L->st = R->ss = 0;
                tt = ts = 0, tag = false;
                L->tag = R->tag = true;
            }
            if (ss || st)
            {
                L->xy += st * L->x + ss * L->y + ss * st * ls;
                L->x2 += ss * L->x + ss * L->x + ss * ss * ls;
                R->xy += st * R->x + ss * R->y + ss * st * rs;
                R->x2 += ss * R->x + ss * R->x + ss * ss * rs;
                L->x += ss * ls, R->x += ss * rs;
                L->y += st * ls, L->y += st * rs;
                L->ss += ss, R->ss += ss;
                L->st += st, R->st += st;
                ss = st = 0;
            }
        }
    };
    
    struct D
    {
        double x, y, x2, xy;
        D () : x (0), y (0), x2 (0), xy (0) {}
        D (double a, double b, double c, double d) : x (a), y (b), x2 (c), xy (d) {}
    };
    
    #define DE printf ("%lf %lf %lf %lf
    ", now->x, now->y, now->x2, now->xy);
    class Segment_Tree
    {
        private :
            
            S_D *Root;
        
            void Build (S_D *&now, int l, int r)
            {
                now = new S_D (l, r);
                if (l == r)
                {
                    now->x = (double)_x[l], now->y = (double)_y[r];
                    now->x2 = now->x * now->x;
                    now->xy = now->x * now->y;
                    return ;
                }
                Build (now->Left, l, now->Mid);
                Build (now->Right, now->Mid + 1, r);
                now->Up ();
            }
    
            void Change_1 (S_D *&now, int l, int r, double s, double t)
            {
                if (l <= now->l && now->r <= r)
                {
                    double L = (now->r - now->l + 1);
                    now->xy += t * now->x + s * now->y + s * t * L;
                    now->x2 += s * now->x + s * now->x + s * s * L;
                    now->x += s * L, now->y += t * L;
                    now->ss += s, now->st += t;
                    return ;
                }
                now->Down ();
                if (l <= now->Mid) Change_1 (now->Left, l, r, s, t);
                if (r > now->Mid) Change_1 (now->Right, l, r, s, t);
                now->Up ();
            }
    
            void Change_2 (S_D *&now, int l, int r, double s, double t)
            {
                if (l <= now->l && now->r <= r)
                {
                    double L = (now->r - now->l + 1);
                    now->tag = true;
                    now->ss = now->st = 0, now->ts = s, now->tt = t;
                    now->x = L * s + _i[now->r] - _i[now->l - 1];
                    now->y = L * t + _i[now->r] - _i[now->l - 1]; 
                    now->xy = L * s * t + (s + t) * (_i[now->r] - _i[now->l - 1]) + i2[now->r] - i2[now->l - 1];
                    now->x2 = L * s * s + 2 * s * (_i[now->r] - _i[now->l - 1]) + i2[now->r] - i2[now->l - 1];
                    return ;
                }
                now->Down ();
                if (l <= now->Mid) Change_2 (now->Left, l, r, s, t);
                if (r > now->Mid) Change_2 (now->Right, l, r, s, t);
                now->Up ();
            }
    
            D Query (S_D *&now, int l, int r)
            {
                if (l <= now->l && now->r <= r)
                    return     D (now->x, now->y, now->x2, now->xy);
                now->Down ();
                D A, B;
                if (l <= now->Mid) A = Query (now->Left, l, r);
                if (r > now->Mid) B = Query (now->Right, l, r);
                A.x += B.x, A.y += B.y;
                A.x2 += B.x2, A.xy += B.xy;
                return A;
            }
    
        public :
    
            inline void Build (int l, int r) { return Build (Root, l, r); }
            
            inline void Change_1 (int l, int r, double s, double t)
            {
                return Change_1 (Root, l, r, s, t);
            }
    
            inline void Change_2 (int l, int r, double s, double t)
            {
                return Change_2 (Root, l, r, s, t);
            }
            
            inline void Query (int l, int r)
            {
                D res = Query (Root, l, r); double s = r - l + 1;
                double b = res.xy - s * (res.x / s) * (res.y / s);
                b /= res.x2 - s * (res.x / s) * (res.x / s);
                printf ("%.10lf
    ", b);
            }
    };
    
    Segment_Tree Seg;
    
    int Main ()
    {
        fread (buf, 1, BUF, stdin);
        int N, M; read (N), read (M);
        register int i; int x;
        for (i = 1; i <= N; ++ i)
            read (x), _x[i] = (double) x;
        for (i = 1; i <= N; ++ i)
            read (x), _y[i] = (double) x;
        int type, y, s, t;
        for (i = 1; i <= N; ++ i)
            _i[i] = _i[i - 1] + i;
        for (i = 1; i <= N; ++ i)
            i2[i] = i2[i - 1] + i * i;
        Seg.Build (1, N);
        for (i = 1; i <= M; ++ i)
        {
            read (type);
            if (type == 1)
            {
                read (x), read (y);
                Seg.Query (x, y);
            }
            else if (type == 2)
            {
                read (x), read (y), read (s), read (t);
                Seg.Change_1 (x, y, (double) s, (double) t);
            }
            else if (type == 3)
            {
                read (x), read (y), read (s), read (t);
                Seg.Change_2 (x, y, (double) s, (double) t);
            }
        }
    
        return 0;
    }
    int ZlycerQan = Main ();
    int main (int argc, char *argv[]) {;}
    /*
        BZOJ 4821: [Sdoi2017]相关分析
        
        
        耗费了整整一下午的时间+晚上的些时间
         
        实在是调不出来了。。。 
        
    */
    #include <cstdio>
    
    #define Max 100090
    #define INF 1e9
    
    #define DEBUG printf ("%lf %lf %lf %lf
    ", now->x, now->y, now->xy, now->pow_two_x);
    
    void read (int &now)
    {
        register char word = getchar ();
        bool temp = false;
        for (now = 0; word < '0' || word > '9'; word = getchar ())
            if (word == '-')
                temp = true;
        for (; word >= '0' && word <= '9'; now = now * 10 + word - '0', word = getchar ());
        if (temp)
            now = -now;
    }
    
    int N, M;
    
    double _x[Max], _y[Max];
    double sum_i[Max], sum_i_2[Max];
    
    struct Data
    {
        double S, T;
    };
    
    struct S_D 
    {
        S_D *Left, *Right;
        int l, r, Mid;
        
        Data Tag_1, Tag_2;
        
        double xy;
        double x, y;
        double pow_two_x;
        
        inline void Up ()
        {
            this->x = this->Left->x + this->Right->x;
            this->y = this->Left->y + this->Right->y;
            
            this->xy = this->Left->xy + this->Right->xy;
            
            this->pow_two_x = this->Left->pow_two_x + this->Right->pow_two_x;
        }
        
        S_D (int __l, int __r) : l (__l), r (__r)
        {
            Left = Right = NULL;
            Mid = __l + __r >> 1;
            
            x = y = 0.0;
            pow_two_x = xy = 0.0;
    
            Tag_1.S = Tag_1.T = 0.0;
            Tag_2.S = Tag_2.T = INF;
        }
        
        inline void Push_Down_2 (double S, double T)
        {
            this->x = (this->r - this->l + 1) * S + sum_i[this->r] - sum_i[this->l - 1];
            this->y = (this->r - this->l + 1) * T + sum_i[this->r] - sum_i[this->l - 1];
            
            this->xy = (this->r - this->l + 1) * S * T + (S + T) * (sum_i[this->r] - sum_i[this->l - 1]) + sum_i_2[this->r] - sum_i_2[this->l - 1];
            
            this->pow_two_x = (this->r - this->l + 1) * S * S + 2 * S * (sum_i[this->r] - sum_i[this->l - 1]) + sum_i_2[this->r] - sum_i_2[this->l - 1];
            
            this->Tag_1.S = this->Tag_1.T = 0.0;
            
            this->Tag_2.S = S;
            this->Tag_2.T = T;
        }
        
        inline void Down ()
        {
            if (this->Tag_1.S || this->Tag_1.T)
            {
                bool temp = false;
                if (this->Left->Tag_2.S != INF || this->Left->Tag_2.T != INF)
                {
                    temp = true;
                    this->Left->Push_Down_2 (this->Tag_1.S + this->Left->Tag_2.S, this->Tag_1.T + this->Left->Tag_2.T);
                }
                if (temp == false)
                {
                    this->Left->xy += this->Tag_1.T * this->Left->x + this->Tag_1.S * this->Left->y + (this->Left->r - this->Left->l + 1) * this->Tag_1.S * this->Tag_1.T;
                    
                    this->Left->pow_two_x += 2.0 * this->Tag_1.S * this->Left->x + (this->Left->r - this->l + 1) * this->Tag_1.S * this->Tag_1.S;
                    
                    this->Left->x += (this->Left->r - this->Left->l + 1) * this->Tag_1.S;
                    this->Left->y += (this->Left->r - this->Left->l + 1) * this->Tag_1.T; 
                
                    this->Left->Tag_1.S += this->Tag_1.S;
                    this->Left->Tag_1.T += this->Tag_1.T;
                }
                temp = false;
                
                if (this->Right->Tag_2.S != INF || this->Right->Tag_2.T != INF)
                {
                    temp = true;
                    this->Right->Push_Down_2 (this->Tag_1.S + this->Right->Tag_2.S, this->Tag_1.T + this->Right->Tag_2.T);
                }
                if (temp == false)
                {
                    this->Right->xy += this->Tag_1.T * this->Right->x + this->Tag_1.S * this->Right->y + (this->Right->r - this->Right->l + 1) * this->Tag_1.S * this->Tag_1.T;
                    
                    this->Right->pow_two_x += 2.0 * this->Tag_1.S * this->Right->x + (this->Right->r - this->l + 1) * this->Tag_1.S * this->Tag_1.S;
                    
                    this->Right->x += (this->Right->r - this->Right->l + 1) * this->Tag_1.S;
                    this->Right->y += (this->Right->r - this->Right->l + 1) * this->Tag_1.T; 
                
                    this->Right->Tag_1.S += this->Tag_1.S;
                    this->Right->Tag_1.T += this->Tag_1.T;
                    
                }
                this->Tag_1.S = this->Tag_1.T = 0.0;
            }
            if (this->Tag_2.S != INF || this->Tag_2.T != INF)
            {
                
                this->Left->Push_Down_2 (this->Tag_2.S, this->Tag_2.T);
                this->Right->Push_Down_2 (this->Tag_2.S, this->Tag_2.T);
                 
                this->Tag_2.S = this->Tag_2.T = INF;
            }
        }
    };
    
    #define DE printf ("%lf %lf %lf %lf
    ", Answer_x, Answer_y, Answer_xy, Answer_x_2);
    
    double Answer_x, Answer_y;
    double Answer_xy, Answer_x_2;
    
    class Segment_Tree_Type
    {
        
        private :
            
            S_D *Root;
            
            
            void __Build_ (S_D *&now, int l, int r)
            {
                now = new S_D (l, r);
                if (l == r)
                {
                    now->x = _x[l];
                    now->y = _y[r];
                    now->xy = now->x * now->y;
                    now->pow_two_x = now->x * now->x;
                    
                    return ;
                }
                __Build_ (now->Left, l, now->Mid);
                __Build_ (now->Right, now->Mid + 1, r);
                
                now->Up ();
            }
            
            void __Change_1_ (S_D *&now, int l, int r, double S, double T)
            {
                if (l <= now->l && now->r <= r)
                {
                    bool temp = false;
                    if (now->Tag_2.S != INF || now->Tag_2.T != INF)
                    {
                        temp = true;
                        now->Push_Down_2 (now->Tag_2.S + S, now->Tag_2.T + T);
                    }
                    if (temp == false)
                    {
                        now->xy += T * now->x + S * now->y + (now->r - now->l + 1) * S * T;
                        now->pow_two_x += 2 * S * now->x + (now->r - now->l + 1) * S * S;
                        
                        now->x += (now->r - now->l + 1) * S;
                        now->y += (now->r - now->l + 1) * T;
                        now->Tag_1.S += S;
                        now->Tag_1.T += T;
                    }
    //                DEBUG
                    return ;
                }
                now->Down ();
                if (l <= now->Mid)
                    __Change_1_ (now->Left, l, r, S, T);
                if (r > now->Mid)
                    __Change_1_ (now->Right, l, r, S, T);
                now->Up ();
            }
            
            void __Change_2_ (S_D *&now, int l, int r, double S, double T)
            {
                if (l <= now->l && now->r <= r)
                {
                    now->Push_Down_2 (S, T); 
    //                DEBUG
                    return ;
                }
                now->Down ();
                if (l <= now->Mid)
                    __Change_2_ (now->Left, l, r, S, T);
                if (r > now->Mid)
                    __Change_2_ (now->Right, l, r, S, T);
                now->Up ();
            }
            
            void __Query_ (S_D *&now, int l, int r)
            {
                if (l <= now->l && now->r <= r)
                {
                    Answer_x += now->x;
                    Answer_y += now->y;
                    Answer_xy += now->xy;
                    Answer_x_2 += now->pow_two_x;
    //                DEBUG
                    return ;
                }
                now->Down ();
                if (l <= now->Mid)
                    __Query_ (now->Left, l, r);
                if (r > now->Mid)
                    __Query_ (now->Right, l, r);
                
                now->Up ();
            }
        public :
            
            inline void Build (int l, int r)
            {
                return __Build_ (Root, l, r);
            }
            
            inline void Change_First (int l, int r, double S, double T)
            {
                return __Change_1_ (Root, l, r, S, T);
            }
            
            inline void Change_Second (int l, int r, double S, double T)
            {
                return __Change_2_ (Root, l, r, S, T);
            }
            
            inline double Query (int l, int r)
            {
                Answer_x = Answer_y = 0;
                Answer_xy = Answer_x_2 = 0;
                __Query_ (Root, l, r);
    //            DE
                double a = (r - l + 1) * Answer_xy - Answer_x * Answer_y;
                double b = (r - l + 1) * Answer_x_2 - Answer_x * Answer_x;
                return a / b;
            }
    };
    
    Segment_Tree_Type Seg;
    
    #define Local
    
    int main (int argc, char *argv[])
    {
    #ifdef Local     
        
        freopen ("relative.in", "r", stdin);
        freopen ("relative.out", "w", stdout);
    
    #endif
        
        read (N);
        read (M);
        int x;
        for (int i = 1; i <= N; i ++)
        {
            sum_i[i] = sum_i[i - 1] + i;
            sum_i_2[i] = sum_i_2[i - 1] + 1.0 * i * i;
        }
        for (int i = 1; i <= N; i ++)
            scanf ("%lf", &_x[i]);
        for (int i = 1; i <= N; i ++)
            scanf ("%lf", &_y[i]);
        
        Seg.Build (1, N);
        for (int y, z, s, type; M --; )
        {
            read (type);
            
            if (type == 1)
            {
                read (x);
                read (y);
                printf ("%.10lf
    ", Seg.Query (x, y));
            }
            else if (type == 2)
            {
                read (x);
                read (y);
                read (z);
                read (s);
                
                Seg.Change_First (x, y, z, s); 
            }
            else
            {
                read (x);
                read (y);
                read (z);
                read (s);
                Seg.Change_Second (x, y, z, s);
            }
        }
        return 0;
    }
  • 相关阅读:
    @property属性装饰器
    信息反馈—冲刺19
    信息反馈—冲刺18
    信息反馈—冲刺17
    淘宝体验评价
    信息反馈—冲刺16
    信息反馈—冲刺15
    第十三周总结
    信息反馈--冲刺14
    查找水王
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7214012.html
Copyright © 2020-2023  润新知