http://codevs.cn/problem/1082/

【AC】

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+;
int n;
ll a[maxn];
ll c1[maxn];
ll c2[maxn];
int lowbit(int x)
{
return x&-x;
}
void add(ll *c,int k,ll val)
{
while(k<=n){
c[k]+=val;
k+=lowbit(k);
}
}
ll query(ll *c,int k)
{
ll ans=;
while(k)
{
ans+=c[k];
k-=lowbit(k);
}
return ans;
}
ll solve(int x)
{
ll ans=;
ans+=x*query(c1,x);
ans-=query(c2,x);
return ans;
}
ll solve(int x,int y)
{
return solve(y)-solve(x-);
}
int main()
{
while(~scanf("%d",&n))
{
a[]=;
for(int i=;i<=n;i++)
{
scanf("%I64d",&a[i]);
// cout<<a[i]<<endl;
add(c1,i,a[i]-a[i-]);
add(c2,i,(i-)*(a[i]-a[i-]));
}
int q;
scanf("%d",&q);
int tp;
while(q--)
{
scanf("%d",&tp);
if(tp==)
{
int x,y;ll val;
scanf("%d%d%I64d",&x,&y,&val);
add(c1,x,val);
add(c1,y+,-val);
add(c2,x,1ll*(x-)*val);
add(c2,y+,-1ll*y*val);
}
else
{
int x,y;
scanf("%d%d",&x,&y);
ll ans=solve(x,y);
printf("%I64d\n",ans);
}
}
}
return ;
}

【原理】

原理是用了差分数组,转载自http://www.cnblogs.com/boceng/p/7222751.html

树状数组时间复杂度为O(MlogN), 实际用的时候优于线段树,且写得少。

神牛是引入了差分数组,要维护的差分数组ks[i] = a[i] - a[i-1]; 可以容易得到a[i] = ks[1] + ks[2] + ... + ks[i]; 即前i项和,为方便记为sigma(ks, i),已经可以看到树状数组的影子了,所以求区间和随之得到

a[1] + a[2] + .. + a[n] = sigma(ks, 1) + sigma(ks, 2) + ... + sigma(ks, n);

= n*ks[1] + (n-1)*ks[2] + ... + 2*ks[n-1] + 1*ks[n];

=  n*(ks[1] + ks[2] +...+ ks[n]) - (0*ks[1] + 1*ks[2] + ... + (n-1)*ks[n]);

所以可以得到 sum[n] =n * sigma(ks, n)  - (0*ks[1] + 1*ks[2] + ... + (n-1)*ks[n]);

令jk[i] = (i-1) * ks[i];

则 sum[n] = n * sigma(ks, n) - sigma(jk, n);

之后便是构造两个树状数组;

 int lowbit(int k){
return k & -k;
}
void add(int n, int *c, int k, int va){
while(k <= n){
c[k] += va;
k += lowbit(k);
}
} //------------------------------------- for(i = ; i <= n; ++i){
add(n, c1, i, jk[i]-jk[i-]);
add(n, c2, i, (i-)*(jk[i]-jk[i-]));
}

然后进行查询求和

 int sigma(int *c, int k){
int sum = ;
while(k){
sum += c[k];
k -= lowbit(k);
}
return sum;
}
int getSum(int s, int t){
return (t*sigma(c1, t)-sigma(c2, t)) - ((s-)*sigma(c1, s-)-sigma(c2, s-));
}

进行单点查询时,只需两个参数均传入该点。

在进行区间更新的时候,神牛市通过两次维护c1,两次c2得到的,但本人推测了几种情况,都不能很好的解释这么做的原因,

 void update(int s, int t, int va){
add(c1, s, va);
add(c1, t+, -va);
add(c2, s, va*(s-));
add(c2, t+, -va*t);
}

【树状数组区间修改区间求和】codevs 1082 线段树练习 3的更多相关文章

  1. Libre OJ 130、131、132 (树状数组 单点修改、区间查询 -> 区间修改,单点查询 -> 区间修改,区间查询)

    这三题均可以用树状数组.分块或线段树来做 #130. 树状数组 1 :单点修改,区间查询 题目链接:https://loj.ac/problem/130 题目描述 这是一道模板题. 给定数列 a[1] ...

  2. codevs 1082 线段树区间求和

    codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...

  3. codevs 1082 线段树练习 3(区间维护)

    codevs 1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...

  4. A Simple Problem with Integers 多树状数组分割,区间修改,单点求职。 hdu 4267

    A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  5. 题解报告:Luogu P3368 【模板】树状数组 2(区间修改,单点查询)

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...

  6. 主席树套树状数组——带修区间第k大zoj2112

    主席树带修第k大 https://www.cnblogs.com/Empress/p/4659824.html 讲的非常好的博客 首先按静态第k大建立起一组权值线段树(主席树) 然后现在要将第i个值从 ...

  7. P3368 【模板】树状数组 2(区间增减,单点查询)

    P3368 [模板]树状数组 2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表 ...

  8. POJ 2155 Matrix【二维树状数组+YY(区间计数)】

    题目链接:http://poj.org/problem?id=2155 Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissio ...

  9. 洛谷 P3368 【模板】树状数组 2(区间加,单点查询)

    题目链接 https://www.luogu.org/problemnew/show/P3368 树状数组 最基础的用法:https://www.cnblogs.com/yinyuqin/p/1096 ...

随机推荐

  1. Selenium私房菜系列9 -- Selenium RC服务器命令行参数列表【ZZ】

    本文转载自:http://wiki.javascud.org/display/SEL/Selenium+Remote+Control+-+options 使用示例: java -jar seleniu ...

  2. 洛谷 P2126 Mzc家中的男家丁

    题目背景 mzc与djn的…还没有众人皆知,所以我们要来宣传一下. 题目描述 mzc家很有钱(开玩笑),他家有n个男家丁,现在mzc要将她们全都聚集起来(干什么就不知道了).现在知道mzc与男家丁们互 ...

  3. codeforces Gym 100338E Numbers (贪心,实现)

    题目:http://codeforces.com/gym/100338/attachments 贪心,每次枚举10的i次幂,除k后取余数r在用k-r补在10的幂上作为候选答案. #include< ...

  4. iterator与iterable

    用Iterator模式实现遍历集合Iterator模式是用于遍历集合类的标准访问方法.它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构.例如,如果没有使用Iterato ...

  5. bfs染色法判定二分图

    #include<iostream> #include<queue> #include<cstring> #include<cstdio> using ...

  6. beta版本发布-团队

    一.β版本于α版本的不同 1.α版本先前只可电脑单机使用,β版本已成功解决联网问题,可以在不同电脑上正常使用 2.β版本相较于α版本修补了较多漏洞.进行了界面的优化且新增了学生个人信息维护功能.教师的 ...

  7. selenium--Xpath定位

    前戏 前面介绍过了七种定位方式,今天来介绍最后一种,也是最强大,本人最常用的定位方式xpath Xpath 即为 xml 路径语言,它是一种用来确定 xml 文档中某部分位置的语言.Xpath 基于 ...

  8. Jarvis OJ-Level4

    借助DynELF实现无libc的漏洞利用小结 #!/usr/bin/env python # coding:utf-8 from pwn import * elf = ELF('level4') wr ...

  9. xampp中php手动升级

    http://windows.php.net/download/           //要下载的 里面有dll文件 http://www.php.net/downloads.php VC9 x86 ...

  10. 相机 感光度iso,焦距,光圈,ccd 和 噪点, 景深关系表格

    表格 矩阵 感官度iso: 越低曝光速度越慢,所谓慢工出细活,成像质量会好,如果形成的话. 但是因为慢,所以要更多的光量,才能画完. 就需要更慢的快门 (但是太慢手抖的话就糊掉,或者动的物体形成轨迹. ...