【BZOJ 4821】【SDOI 2017】相关分析

把公式化开来得到:
a=ri=l(xiyix¯yixiy¯+x¯y¯)ri=l(x2i2x¯xi+x¯2)
把分子的第二项拿出来结合 ri=l 就可以得到 x¯ri=lyi=x¯y¯(rl+1) ,第三项同理,分母同理,再合并一下就可以得到:
a=xiyix¯y¯(rl+1)ri=lx2ix¯2(rl+1)
然后用线段树维护一下 x y xy x2 即可。

2号询问就是个简单的区间加,注意到:
(x+Δx)(y+Δy)
=(xy+Δxy+Δyx+ΔxΔy)
=xy+yΔx+xΔy+ΔxΔy ,就可以维护了。
3号询问可以看做是先将第i号元素变为i然后执行一次2号操作。用一下平方和公式即可。
注意:当执行3号操作的覆盖操作时要将所有2号操作的lazy-tag清除掉。

#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define ls x<<1
#define rs x<<1|1
#define N 100005
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct TREE{double sumx,sumy,sumxy,sumxx,tag_x,tag_y; int l,r,len,tag_c;} tree[N*4];
double xx[N],yy[N];
int n,m,i,opt,l,r,dx,dy;
void pushup(int x)
{
    tree[x].sumx = tree[ls].sumx + tree[rs].sumx;
    tree[x].sumy = tree[ls].sumy + tree[rs].sumy;
    tree[x].sumxy = tree[ls].sumxy + tree[rs].sumxy;
    tree[x].sumxx = tree[ls].sumxx + tree[rs].sumxx;
}
void build(int x,int l,int r)
{
    tree[x].len = r - l + 1; tree[x].l = l; tree[x].r = r;
    if (l == r) 
        {
            tree[x].sumx = xx[l]; tree[x].sumy = yy[l];
            tree[x].sumxy = xx[l] * yy[l]; 
            tree[x].sumxx = xx[l] * xx[l];
            return;
        }
    int mid = (l + r) >> 1;
    build(ls,l,mid); build(rs,mid+1,r); pushup(x);
    }
double calc(int x) {return (double)x*(x+1)*(2*x+1)/6;}
void update_a(int x,double dx,double dy)
{
    tree[x].sumxy += tree[x].sumx * dy + tree[x].sumy * dx + tree[x].len * dx * dy;
    tree[x].sumxx += tree[x].sumx * dx * 2 + tree[x].len * dx * dx;
    tree[x].sumx += dx * tree[x].len;
    tree[x].sumy += dy * tree[x].len;
    tree[x].tag_x += dx; tree[x].tag_y += dy;
}
void update_c(int x)
{
    tree[x].sumx = tree[x].sumy = (double)(tree[x].l+tree[x].r)*tree[x].len/2;
    tree[x].sumxy = tree[x].sumxx = calc(tree[x].r) - calc(tree[x].l-1);
    tree[x].tag_c = 1;
    tree[x].tag_x = tree[x].tag_y = 0;
}
void pushdown(int x)
{
    if (tree[x].tag_c) {update_c(ls); update_c(rs); tree[x].tag_c = 0;}
    if (tree[x].tag_x || tree[x].tag_y)
        {
            update_a(ls,tree[x].tag_x,tree[x].tag_y);
            update_a(rs,tree[x].tag_x,tree[x].tag_y);
            tree[x].tag_x = tree[x].tag_y = 0;
        }
}
void add(int x,int l,int r,int L,int R,int dx,int dy)
{
    if (L <= l && r <= R) {update_a(x,dx,dy); return;}
    pushdown(x);
    int mid = (l + r) >> 1;
    if (L <= mid) add(ls,l,mid,L,R,dx,dy);
    if (mid < R) add(rs,mid+1,r,L,R,dx,dy);
    pushup(x);
}
void change(int x,int l,int r,int L,int R)
{
    if (L <= l && r <= R) {update_c(x); return;}
    pushdown(x);
    int mid = (l + r) >> 1;
    if (L <= mid) change(ls,l,mid,L,R);
    if (mid < R) change(rs,mid+1,r,L,R);
    pushup(x);
}
double query(int x,int l,int r,int L,int R,int opt)
{
    if (L <= l && r <= R) 
        {
            if (opt == 1) return tree[x].sumx;
            if (opt == 2) return tree[x].sumy;
            if (opt == 3) return tree[x].sumxy;
            if (opt == 4) return tree[x].sumxx;
        }
    pushdown(x);
    int mid = (l + r) >> 1; double res = 0;
    if (L <= mid) res += query(ls,l,mid,L,R,opt);
    if (mid < R) res += query(rs,mid+1,r,L,R,opt);
    return res;
}
int main()
{
    scanf("%d%d",&n,&m);
    fo(i,1,n) scanf("%lf",&xx[i]);
    fo(i,1,n) scanf("%lf",&yy[i]);
    build(1,1,n);
    while (m--)
        {
            scanf("%d",&opt);
            scanf("%d%d",&l,&r);
            if (opt == 1)
                {
                    double res1 = query(1,1,n,l,r,1); double res2 = query(1,1,n,l,r,2);
                    double res3 = query(1,1,n,l,r,3); double res4 = query(1,1,n,l,r,4);
                    double p = res3 - res1 * res2 / (r-l+1);
                    double q = res4 - res1 * res1 / (r-l+1);
                    printf("%.10lf\n",p/q);
                }   else
                {
                    scanf("%d%d",&dx,&dy);
                    if (opt == 3) change(1,1,n,l,r);
                    add(1,1,n,l,r,dx,dy);
                }       
        }
    return 0;   
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: bzoj作为一个计算机竞赛的在线评测系统,不仅可以提供大量的题目供程序员练习和学习,还可以帮助程序员提升算法和编程能力。为了更好地利用bzoj进行题目的学习和刷题,制定一个bzoj做题计划是非常有必要的。 首先,我们需要合理安排时间,每天留出一定的时间来做bzoj的题目。可以根据自己的时间安排,每天挑选适量的题目进行解答。可以先从难度较低的题目开始,逐渐提高难度,这样既能巩固基础知识,又能挑战自己的思维能力。 其次,要有一个计划和目标。可以规划一个每周或每月的题目数量目标,以及每个阶段要学习和掌握的算法知识点。可以根据bzoj的题目分类,如动态规划、图论、贪心算法等,结合自己的实际情况,有针对性地选择题目进行学习。 此外,要充分利用bzoj提供的资源。bzoj网站上有很多高质量的题解和优秀的解题代码,可以参考和学习。还有相关的讨论区,可以与其他程序员交流和讨论,共同进步。 最后,要坚持并保持思考。做题不是单纯为了刷数量,更重要的是学会思考和总结。遇到难题时,要有耐心,多思考,多尝试不同的解法。即使不能一次性解出来,也要学会思考和分析解题过程,以及可能出现的错误和优化。 总之,bzoj做题计划的关键在于合理安排时间、制定目标、利用资源、坚持思考。通过有计划的刷题,可以提高算法和编程能力,并培养解决问题的思维习惯,在计算机竞赛中取得更好的成绩。 ### 回答2: bzoj做题计划是指在bzoj这个在线测评系统上制定一套学习和刷题的计划,并且将计划记录在excel表格中。该计划主要包括以下几个方面的内容。 首先是学习目标的设定。通过分析自己的水平和知识缺口,可以设定一个合理的目标,比如每天解决一定数量的题目或者提高特定的算法掌握程度。 其次是题目选择的策略。在excel表格中可以记录下自己选择的题目编号、题目类型和难度等信息。可以根据题目的类型和难度来安排每天的刷题计划,确保自己可以逐步提高技巧和解题能力。 然后是学习进度的记录和管理。将每天的完成情况记录在excel表格中,可以清晰地看到自己的学习进度和任务完成情况。可以使用图表等功能来对学习进度进行可视化展示,更好地管理自己的学习计划。 同时,可以在excel表格的备注栏中记录下每道题目的解题思路、关键点和需要复习的知识点等信息。这样可以方便自己回顾和总结,巩固所学的知识。 最后,可以将excel表格与其他相关资料进行整合,比如算法教材、题目解析和学习笔记等。这样可以形成一个完整的学习档案,方便自己进行系统的学习和复习。 总之,bzoj做题计划excel的制定和记录可以帮助我们更加有条理和高效地进行学习和刷题。通过合理安排学习目标和题目选择策略,记录学习进度和思路,并整合其他学习资料,我们可以提高自己的解题能力,并在bzoj上取得更好的成绩。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值