• 【高手训练】【树状数组】电子速度


    <高手训练例题>

    正片开始

    电子速度

    题目

    选取显像管的任意一个平面,一开始平面内有(n)个电子,初始速度分别为(v_i),定义飘升系数为:

    [sum_{1leq i leq j leq n} |v_i imes v_j|^2( imes表示叉乘) ]

    电子的速度常常会发生变化。也就是说,有两种类型的操作:

    (1 p x y)(p) 改为((x, y))

    (2 l r)询问 ([l, r]) 这段区间内的电子的飘升系数。

    答案对 (20170927) 取模即可。

    Solution

    观察答案并推导:

    [egin{aligned} ans &= sum_{1 leq i < j leq n} mathrm{(x_iy_j - x_jy_i)^2} \ &=sum_{1 leq i < j leq n} mathrm{x_i^2y_j^2} + sum_{1 leq i < j leq n} mathrm{x_j^2y_i^2} - 2sum_{1 leq i < j leq n}mathrm{x_ix_jy_iy_j}\ &=sum_{1 leq i, j leq n}mathrm{[i ≠j]x_i^2y_j^2} - sum_{1 leq i,j leq n}mathrm{[i ≠ j] (x_iy_i cdot x_jy_j)} \ &= (sum_{i = 1}^{n}mathrm{x_i^2} cdot sum_{i = 1}^{n}mathrm{y_i^2} - sum_{i = 1}^{n}mathrm{(x_i^2y_i^2) })- mathrm{(sum_{i = 1}^{n} x_iy_i cdot sum_{i = 1}^{n}x_iy_i - sum_{i = 1}^{n}(x_iy_i)^2)} \ &=mathrm{sum_{i = 1}^{n}x_i^2 cdot sum_{i = 1}^{n}y_i^2 - (sum_{i = 1}^{n} x_iy_i)^2} end{aligned} ]

    三个树状数组维护三个值(sum_{i = 1}^n x_i^2)(sum_{i = 1}^n y_i^2)(sum_{i = 1}^nx_iy_j),三个值。这样就可以支持修改操作并快速维护答案了。

    (mathrm{Code:})

    #include <bits/stdc++.h>
    #define N 1000110
    #define mod 20170927
    using namespace std;
    int n, m;
    
    inline int add(int a, int b) {
        if (b < 0)
            return (a + b < 0 ? a + b + mod : a + b);
        else
            return (a + b >= mod ? a + b - mod : a + b);
    }// add函数把加减写一起
    inline int del(int a, int b) { return a - b < 0 ? a - b + mod : a - b; }
    inline int mul(int a, int b) { return 1LL * a * b % mod; }
    
    inline int read() {
        int s = 0, w = 1;
        char c = getchar();
        while ((c > '9' || c < '0') && c != '-') c = getchar();
        if (c == '-') w = -1, c = getchar();
        while (c <= '9' && c >= '0')
            s = (s << 3) + (s << 1) + c - '0', c = getchar();
        return s * w;
    }
    void write(int x) {
        if (x < 0) x = ~x + 1, putchar('-');
        if (x > 9) write(x / 10);
        putchar(x % 10 + 48);
        return void();
    }
    
    struct vec {
        int x, y;
        vec() {}
        vec(int _x, int _y) {
            x = _x;
            y = _y;
        }
        inline vec operator-() { return vec(-x, -y); }
    } v[N];
    struct BIT {
        int a[N], b[N], c[N];
        void Inc(int x, vec v, int w) { //w为加&减的处理。
            for (; x <= n; x += x & (-x)) {
                a[x] = add(a[x], w * mul(v.x, v.x));
                b[x] = add(b[x], w * mul(v.y, v.y));
                c[x] = add(c[x], w * mul(v.x, v.y));
            }
        }
        int aska(int x) {
            int sum = 0;
            for (; x; x -= x & (-x)) sum = add(sum, a[x]);
            return sum;
        }
        int askb(int x) {
            int sum = 0;
            for (; x; x -= x & (-x)) sum = add(sum, b[x]);
            return sum;
        }
        int askc(int x) {
            int sum = 0;
            for (; x; x -= x & (-x)) sum = add(sum, c[x]);
            return sum;
        }
        int Ask(int l, int r) {
            int s1 = del(aska(r), aska(l - 1));
            int s2 = del(askb(r), askb(l - 1));
            int s3 = del(askc(r), askc(l - 1));
            return del(mul(s1, s2), mul(s3, s3));
        }
    } B;
    signed main() {
        n = read();
        m = read();
        for (int i = 1; i <= n; ++i) {
            int x = read(), y = read();
            v[i] = vec(x, y);
            B.Inc(i, v[i], 1);
        }
        for (int i = 1; i <= m; ++i) {
            int opt = read();
            if (opt == 1) {
                int p = read(), x = read(), y = read();
                vec tmp = vec(x, y);
                B.Inc(p, v[p], -1);
                B.Inc(p, tmp, 1);
                v[p] = tmp;
            }
            if (opt == 2) {
                int x = read(), y = read();
                write(B.Ask(x, y));
                putchar(10);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    关于Xil_Assert断言产生的死循环,导致程序未执行的问题
    Unable to connect to ps7_cortexa9的参考解决方案Zedboard,zynq
    Xilinx SDK下载时出现的几个问题总结
    深入分析SCU GIC驱动 1 ZEDBOARD,ZYNQ7000
    Git命令行介绍和使用说明(持续更新)
    常用快捷键—Webstorm入门指南
    数组和链表的关系
    把Sublime Text 2固定到Ubuntu启动器
    Node的Eclipse插件 Nodeclipse
    Sublime 自定义格式化快捷键
  • 原文地址:https://www.cnblogs.com/yywxdgy/p/13098949.html
Copyright © 2020-2023  润新知