• 相关分析 BZOJ 4821


    相关分析

    【问题描述】

    Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度、颜色等等,进而估算出星星的距离,半径等等。Frank不仅喜欢观测,还喜欢分析观测到的数据。他经常分析两个参数之间(比如亮度和半径)是否存在某种关系。现在Frank要分析参数X与Y之间的关系。他有n组观测数据,第i组观测数据记录了x_i和y_i。他需要一下几种操作1 L,R:用直线拟合第L组到底R组观测数据。用xx表示这些观测数据中x的平均数,用yy表示这些观测数据中y的平均数,即
    xx=Σx_i/(R-L+1)(L<=i<=R)
    yy=Σy_i/(R-L+1)(L<=i<=R)
    如果直线方程是y=ax+b,那么a应当这样计算:
    a=(Σ(x_i-xx)(y_i-yy))/(Σ(x_i-xx)(x_i-xx)) (L<=i<=R)
    你需要帮助Frank计算a。
    2 L,R,S,T:
    Frank发现测量数据第L组到底R组数据有误差,对每个i满足L <= i <= R,x_i需要加上S,y_i需要加上T。
    3 L,R,S,T:
    Frank发现第L组到第R组数据需要修改,对于每个i满足L <= i <= R,x_i需要修改为(S+i),y_i需要修改为(T+i)。

    【输入格式】

    第一行两个数n,m,表示观测数据组数和操作次数。
    接下来一行n个数,第i个数是x_i。
    接下来一行n个数,第i个数是y_i。
    接下来m行,表示操作,格式见题目描述。
    1<=n,m<=10^5,0<=|S|,|T|,|x_i|,|y_i|<=10^5
    保证1操作不会出现分母为0的情况。

    【输出格式】

    对于每个1操作,输出一行,表示直线斜率a。

    选手输出与标准输出的绝对误差不超过10^-5即为正确。

    【样例输入】

    3 5
    1 2 3
    1 2 3
    1 1 3
    2 2 3 -3 2
    1 1 2
    3 1 2 2 1
    1 1 3

    【样例输出】

    1.0000000000
    -1.5000000000
    -0.6153846154


    题解:

    对于线性回归方程我们把它拆分,x平方和,x权值和,y权值和,xy权值和,x平方和

    第二个第三个操作用初中学的完全平方公式拆一拆就好了

    记得爆 long long MMP

      1 #include<cmath>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<algorithm>
      7 using namespace std;
      8 inline void Scan(int &x)
      9 {
     10     char c;
     11     bool o = false;
     12     while(!isdigit(c = getchar()))
     13         if(c == '-')
     14             o = true;
     15     x = c - '0';
     16     while(isdigit(c = getchar()))
     17         x = x * 10 + c - '0';
     18     if(o) x = -x;
     19 }
     20 const int maxn = 1e5 + 1;
     21 const int maxs = maxn << 2;
     22 struct ele
     23 {
     24     long long x, y;
     25     double xy, sx;
     26     inline void print()
     27     {
     28         printf("%lf %lf %lf %lf
    ", (double) x, (double) y, (double) xy, (double) sx);
     29     }
     30     inline void empty()
     31     {
     32         x = y = xy = sx = 0;
     33     }
     34 };
     35 struct tag
     36 {
     37     long long s, t;
     38     inline bool exist()
     39     {
     40         return s || t;
     41     }
     42     inline void empty()
     43     {
     44         s = t = 0;
     45     }
     46 };
     47 tag mark[maxs], sign[maxs];
     48 ele ans, add;
     49 ele tr[maxs];
     50 int n, m;
     51 int x[maxn], y[maxn];
     52 double sum[maxn];
     53 inline ele operator + (ele a, ele b)
     54 {
     55     return (ele) {a.x + b.x, a.y + b.y, a.xy + b.xy, a.sx + b.sx};
     56 }
     57 inline tag operator + (tag a, tag b)
     58 {
     59     return (tag) {a.s + b.s, a.t + b.t};
     60 }
     61 void Build(int k, int l, int r)
     62 {
     63     if(l == r)
     64     {
     65         tr[k] = (ele) {x[l], y[l], (double) x[l] * y[l], (double) x[l] * x[l]};
     66         return;
     67     }
     68     int mi = l + r >> 1;
     69     int lc = k << 1, rc = k << 1 | 1;
     70     Build(lc, l, mi), Build(rc, mi + 1, r);
     71     tr[k] = tr[lc] + tr[rc];
     72 }
     73 inline void Add(int k, int n, long long s, long long t)
     74 {
     75     long long x, y;
     76     double xy, sx;
     77     x = n * s;
     78     y = n * t;
     79     xy = (double) s * tr[k].y + (double) t * tr[k].x + (double) n * s * t;
     80     sx = (double) n * s * s + 2 * s * (double) tr[k].x;
     81     add = (ele) {x, y, xy, sx};
     82     tr[k] = tr[k] + add;
     83     mark[k] = mark[k] + (tag) {s, t};
     84 }
     85 inline long long Sum(long long l, long long r, int n)
     86 {
     87     return (l + r) * n / 2;
     88 }
     89 inline void Change(int k, double s, double t, int l, int r)
     90 {
     91     int n = r - l + 1;
     92     double x, y, xy, sx;
     93     x = Sum(s + l, s + r, n);
     94     y = Sum(t + l, t + r, n);
     95     xy = (double) n * s * t + (double) (s + t) * Sum(l, r, n) + sum[r] - sum[l - 1];
     96     sx = (double) n * s * s + sum[r] - sum[l - 1] + (double) 2 * s * Sum(l, r, n);
     97     tr[k] = (ele) {x, y, xy, sx};
     98     sign[k] = (tag) {s, t};
     99     mark[k].empty();
    100 }
    101 inline void Down(int k, int l, int r)
    102 {
    103     int lc = k << 1, rc = k << 1 | 1;
    104     int mi = l + r >> 1;
    105     double s, t;
    106     if(sign[k].exist())
    107     {
    108         s = sign[k].s, t = sign[k].t;
    109         Change(lc, s, t, l, mi), Change(rc, s, t, mi + 1, r);
    110         sign[k].empty();
    111     }
    112     if(mark[k].exist())
    113     {
    114         s = mark[k].s, t = mark[k].t;
    115         Add(lc, mi - l + 1, s, t), Add(rc, r - mi, s, t);
    116         mark[k].empty();
    117     }
    118 }
    119 void Query(int k, int l, int r, int x, int y)
    120 {
    121     if(x <= l && r <= y)
    122     {
    123         ans = ans + tr[k];
    124         return;
    125     }
    126     Down(k, l, r);
    127     int mi = l + r >> 1;
    128     if(x <= mi) Query(k << 1, l, mi, x, y);
    129     if(y > mi) Query(k << 1 | 1, mi + 1, r, x, y);
    130 }
    131 void Insert(int k, int l, int r, int x, int y, int s, int t)
    132 {
    133     if(x <= l && r <= y)
    134     {
    135         Add(k, r - l + 1, s, t);
    136         return;
    137     }
    138     Down(k, l, r);
    139     int mi = l + r >> 1;
    140     int lc = k << 1, rc = k << 1 | 1;
    141     if(x <= mi) Insert(lc, l, mi, x, y, s, t);
    142     if(y > mi) Insert(rc, mi + 1, r, x, y, s, t);
    143     tr[k] = tr[lc] + tr[rc];
    144 }
    145 void Modify(int k, int l, int r, int x, int y, int s, int t)
    146 {
    147     if(x <= l && r <= y)
    148     {
    149         Change(k, s, t, l, r);
    150         return;
    151     }
    152     Down(k, l, r);
    153     int mi = l + r >> 1;
    154     int lc = k << 1, rc = k << 1 | 1;
    155     if(x <= mi) Modify(lc, l, mi, x, y, s, t);
    156     if(y > mi) Modify(rc, mi + 1, r, x, y, s, t);
    157     tr[k] = tr[lc] + tr[rc];
    158 }
    159 int main()
    160 {
    161     Scan(n), Scan(m);
    162     for(int i = 1; i <= n; ++i) Scan(x[i]);
    163     for(int i = 1; i <= n; ++i) Scan(y[i]);
    164     for(int i = 1; i <= n; ++i) sum[i] = sum[i - 1] + (double) i * i;
    165     Build(1, 1, n);
    166     int o, x, y, s, t;
    167     int len;
    168     long long meanx;
    169     long double up, down, meany;
    170     while(m--)
    171     {
    172         Scan(o), Scan(x), Scan(y);
    173         switch(o)
    174         {
    175             case 1:
    176             {
    177                 ans.empty();
    178                 Query(1, 1, n, x, y);
    179                 len = y - x + 1;
    180                 meanx = ans.x;
    181                 meany = (double) ans.y / len;
    182                 up = ans.xy - meanx * meany;
    183                 down = ans.sx - (double) meanx * meanx / len;
    184                 double answer = up / down;
    185                 printf("%.10lf
    ", answer);
    186                 break;
    187             }
    188             case 2:
    189             {
    190                 Scan(s), Scan(t);
    191                 Insert(1, 1, n, x, y, s, t);
    192                 break;
    193             }
    194             case 3:
    195             {
    196                 Scan(s), Scan(t);
    197                 Modify(1, 1, n, x, y, s, t);
    198                 break;
    199             }
    200         }
    201     }
    202 }
  • 相关阅读:
    mysql进阶
    浅谈数据库查询操作时的顺序
    Problem C Emergency Evacuation 一道思维题
    c++随机生成树
    洛谷 P4408 [NOI2003]逃学的小孩
    UVA11300 Spreading the Wealth
    洛谷 P3574 [POI2014]FAR-FarmCraft
    洛谷 P2882 [USACO07MAR]Face The Right Way G
    JSOI BZOJ4472 salesman
    CF 1912 A NEKO's Maze Game
  • 原文地址:https://www.cnblogs.com/lytccc/p/6757930.html
Copyright © 2020-2023  润新知