维护平方和

题目:长度为n的数列
两种操作:1为区间所有的数加一个数
2为求区间的平方和

线段树的核心是维护lazy和tree
lazy是存操作(维护操作)
tree是存结果(维护结果)

此题建完树的结果为 a*a+b*b+c*c
操作后的结果  (a+A)*(a+A)+(b+A)*(b+A)+(c+A)*(c+A)
           = (a*a+b*b+c*c) + 3*A*A + 2* (a+b+c) *A
                 ||                         ||
                 \/                         \/
             平方和(未操作前的结果)          和
==> 操后结果=操前结果+len*(操作数)*(操作数)+2*(朴素和)*操作数
所以不仅要维护操后结果(平方和),还要维护朴素和

维护tree
可以比较操前结果和操后结果的异同
再判断要维护几个tree和哪些东西
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int const N=1e5+7;
int n,m;
int a[N];
int ly[N<<2];
struct L{
    int a,b;
}tr[N<<2];
void bulid(int p,int l,int r){
    if(l==r){ tr[p].a=a[l]; tr[p].b=a[l]*a[l];return ; }
    int mid=(l+r) >> 1;
    bulid(p*2,l,mid);
    bulid(p*2+1,mid+1,r);
    tr[p].a = tr[p*2].a + tr[p*2+1].a ;
    tr[p].b =tr[p*2].b + tr[p*2+1].b;    
}
void pushdown(int p,int len){
    tr[p*2].b += 2*tr[p*2].a*ly[p] + (len-len/2)*ly[p]*ly[p];
    tr[p*2].a += ly[p]*(len-len/2);
    tr[p*2+1].b += 2*tr[p*2+1].a*ly[p] + len/2*ly[p]*ly[p];    
    tr[p*2+1].a += ly[p]*len/2;
    ly[p*2] += ly[p]; ly[p*2+1] += ly[p];
    ly[p] = 0;
}
void add(int p,int l,int r,int x,int y,int k){
    if(x<=l&&r<=y){
        tr[p].b += 2*tr[p].a*k + (r-l+1)*k*k;
        tr[p].a +=(r-l+1)*k;
        ly[p]+=k;
        return ;
    }
    pushdown(p,r-l+1);
    int mid=(l+r) >> 1;
    if(x<=mid) add(p*2,l,mid,x,y,k);
    if(y>=mid+1) add(p*2+1,mid+1,r,x,y,k);
    tr[p].a = tr[p*2].a + tr[p*2+1].a ;
    tr[p].b = tr[p*2].b + tr[p*2+1].b ;
}
int ask(int p,int l,int r,int x,int y){
    if(x<=l&&r<=y){
        return tr[p].b ;
    }
    pushdown(p,r-l+1);
    int mid = (l+r) >> 1;
    int res=0;
    if(x<=mid) res+=ask(p*2,l,mid,x,y);
    if(mid+1<=y) res+=ask(p*2+1,mid+1,r,x,y);
    return res;
}
int main(){
    cin >> n >> m;
    for(int i=1;i<=n;++i){
        cin >> a[i];
    }
    bulid(1,1,n);
    while(m--){
        int op,x,y,k;
        cin >> op >> x >> y;
        if(op==1){
            cin >> k;
            add(1,1,n,x,y,k);
        }
        else cout << ask(1,1,n,x,y) << "\n";
    }
    return 0;
}
线段树和数状数组经典例题 文章被收录于专栏

线段树和数状数组经典例题

全部评论

相关推荐

03-03 23:12
已编辑
北京邮电大学 Java
书海为家:我来给一点点小建议,因为毕竟还在学校不像工作几年的老鸟有丰富的项目经验,面试官在面试在校生的时候更关注咱们同学的做事逻辑和思路,所以最好在简历中描述下自己做过项目的完整过程,比如需求怎么来的,你对需求的解读,你想到的解决办法,遇到困难如何找人求助,最终项目做成了什么程度,你从中收获了哪些技能,你有什么感悟。
你的简历改到第几版了
点赞 评论 收藏
分享
02-28 01:18
已编辑
南昌大学 后端工程师
后测速成辅导一两个月...:把开源经历放个人项目上边应该更好,就像大部分人都把实习经历放个人项目上边
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 春招至今,你的战绩如何? #
11086次浏览 95人参与
# 你的实习产出是真实的还是包装的? #
1960次浏览 42人参与
# 巨人网络春招 #
11371次浏览 223人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7643次浏览 43人参与
# 简历第一个项目做什么 #
31749次浏览 341人参与
# 重来一次,我还会选择这个专业吗 #
433551次浏览 3926人参与
# MiniMax求职进展汇总 #
24121次浏览 309人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187211次浏览 1122人参与
# 牛客AI文生图 #
21447次浏览 238人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152456次浏览 888人参与
# 研究所笔面经互助 #
118967次浏览 577人参与
# 简历中的项目经历要怎么写? #
310370次浏览 4219人参与
# AI时代,哪些岗位最容易被淘汰 #
63836次浏览 828人参与
# 面试紧张时你会有什么表现? #
30513次浏览 188人参与
# 你今年的平均薪资是多少? #
213146次浏览 1039人参与
# 你怎么看待AI面试 #
180146次浏览 1258人参与
# 高学历就一定能找到好工作吗? #
64331次浏览 620人参与
# 你最满意的offer薪资是哪家公司? #
76546次浏览 374人参与
# 我的求职精神状态 #
448136次浏览 3129人参与
# 正在春招的你,也参与了去年秋招吗? #
363523次浏览 2638人参与
# 腾讯音乐求职进展汇总 #
160677次浏览 1112人参与
# 校招笔试 #
471210次浏览 2964人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务