POJ 3468 A Simple Problem with Integers(树状数组区间更新) 续
这个题刚开始的时候是套模板的,并没有真的理解什么树状数组的区间更新,这几天想了一下,下面是总结:
区间更新这里引进了一个数组delta数组,delta[i]表示区间 [i, n] 的共同增量,每次你需要更新的时候只需要更新delta数组就行了,因为每段区间更新的数都记录在这个数组中,那怎么查询前缀和呐?
sum[i]=a[1]+a[2]+a[3]+......+a[i]+delta[1]*(i-0)+delta[2]*(i-1)+delta[3]*(i-2)+......+delta[i]*(i-i+1);
= sigma( a[x] ) + sigma( delta[x] * (i + 1 - x) )
= sigma( a[x] ) + (i + 1) * sigma( delta[x] ) - sigma( delta[x] * x )
红字不难理解就是从当前位置到i区间共同的增量乘上当前位置到i有多少个数就是增加的总量;具体写到代码中怎么体现?还是以这个题为例:
#include<iostream>
#include<stdio.h>
#include<string.h>
#define N 100010
#define ll long long
using namespace std;
ll c1[N];//delta的前缀和
ll c2[N];//delta * i的前缀和
ll ans[N];//存放的前缀和
ll n,m;
string op;
ll lowbit(ll x)
{
return x&(-x);
}
void update(ll x,ll val,ll *c)
{
while(x<=n)
{
c[x]+=val;
x+=lowbit(x);
}
}
ll getsum(ll x,ll *c)
{
ll s=;
while(x>)
{
s+=c[x];
x-=lowbit(x);
}
return s;
}
int main()
{
freopen("C:\\Users\\acer\\Desktop\\in.txt","r",stdin);
while(scanf("%lld%lld",&n,&m)!=EOF)
{
memset(c1,,sizeof c1);
memset(c2,,sizeof c2);
memset(ans,,sizeof ans);
for(int i=;i<=n;i++)
{
scanf("%lld",&ans[i]);
ans[i]+=ans[i-];
}
getchar();
for(int i=;i<=m;i++)
{
cin>>op;
if(op=="C")
{
ll s1,s2,s3;
scanf("%lld%lld%lld",&s1,&s2,&s3);
update(s1,s3,c1);//delta的前缀和 更新
update(s2+,-s3,c1);
update(s1,s1*s3,c2);//delta * i的前缀和 更新
update(s2+,-(s2+)*s3,c2);
}
else if(op=="Q")
{
/*
sigma( a[x] ) + (i + 1) * sigma( delta[x] ) - sigma( delta[x] * x )
*/ ll s1,s2;
scanf("%lld%lld",&s1,&s2);
/*sigma( a[x] )*/
ll cur=ans[s2]-ans[s1-];//首先等于s1~s2这个区间的基础值
/*(i + 1) * sigma( delta[x] )*/
cur+=getsum(s2,c1)*(s2+)-getsum(s2,c2);//0~s2对前缀和的影响
/*sigma( delta[x] * x )*/
cur-=getsum(s1-,c1)*(s1)-getsum(s1-,c2);//0~s1对前缀和的影响
printf("%lld\n",cur);
}
}
}
}
POJ 3468 A Simple Problem with Integers(树状数组区间更新) 续的更多相关文章
- POJ3468 A Simple Problem With Integers 树状数组 区间更新区间询问
今天学了很多关于树状数组的技巧.一个是利用树状数组可以简单的实现段更新,点询问(二维的段更新点询问也可以),每次修改只需要修改2个角或者4个角就可以了,另外一个技巧就是这题,原本用线段树做,现在可以用 ...
- HDU 4267 A Simple Problem with Integers --树状数组
题意:给一个序列,操作1:给区间[a,b]中(i-a)%k==0的位置 i 的值都加上val 操作2:查询 i 位置的值 解法:树状数组记录更新值. 由 (i-a)%k == 0 得知 i%k == ...
- A Simple Problem with Integers(树状数组HDU4267)
A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (J ...
- POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询)
POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询) 题意分析 注意一下懒惰标记,数据部分和更新时的数字都要是long long ,别的没什么大 ...
- poj 3468 A Simple Problem with Integers 【线段树-成段更新】
题目:id=3468" target="_blank">poj 3468 A Simple Problem with Integers 题意:给出n个数.两种操作 ...
- 线段树(成段更新) POJ 3468 A Simple Problem with Integers
题目传送门 /* 线段树-成段更新:裸题,成段增减,区间求和 注意:开long long:) */ #include <cstdio> #include <iostream> ...
- poj 3468 A Simple Problem with Integers(线段树+区间更新+区间求和)
题目链接:id=3468http://">http://poj.org/problem? id=3468 A Simple Problem with Integers Time Lim ...
- POJ 3468 A Simple Problem with Integers(线段树功能:区间加减区间求和)
题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS Memory Limit ...
- POJ 3468 A Simple Problem with Integers(分块入门)
题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS Memory Limit ...
- 【poj2155】Matrix(二维树状数组区间更新+单点查询)
Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the ...
随机推荐
- grunt学习笔记1 理论知识
你需要检查js语法错误,然后再去压缩js代码.如果这两步你都去手动操作,会耗费很多成本.Grunt就能让你省去这些手动操作的成本. “—save-dev”的意思是,在当前目录安装grunt的同时,顺便 ...
- Linux 文件查找
在Linux系统的查找相关的命令: which 查看可执行文件的位置 whereis 查看文件的位置 locate 配合数据库查看文件位置 find 实际搜寻硬盘查询文件名称 whereis wher ...
- oracle 权限
一.介绍这一部分我们主要看看oracle中如何管理权限和角色,权限和角色的区别在哪里.当刚刚建立用户时,用户没有任何权限,也不能执行任何操作.如果要执行某种特定的数据库操作,则必须为其授予系统的权限: ...
- P3377
题目描述 如题,一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或第y个数已经被删除或第x和第y个数在用一个堆 ...
- WordPress-基础设置之常规设置
对于第一次使用Wordpress系统的朋友,请先别着急发布文章及进行其他操作,为了更加科学的使用及管理wordpress,应该需要对其进行相关设置,主要涉及3个部分,一.常规设置,二.阅读设置,三.固 ...
- clone github报Permission denied (publickey) 解决方案
问题描述 问题产生的原因,不是很清楚,就不管了.在执行git clone git@github.com:****.git 的时候报了Permission denied (publickey). War ...
- Python自学笔记-time模块(转)
在Python中,通常有这几种方式来表示时间:1)时间戳 2)格式化的时间字符串 3)元组(struct_time)共九个元素.由于Python的time模块实现主要调用C库,所以各个平台可能有所不同 ...
- jdbc-大数据存储
jdbc-大数据存储 1 什么是大数据 所谓大数据,就是大的字节数据,或大的字符数据.标准SQL中提供了如下类型来保存大数据类型: 类型 长度 tinyblob 28--1B(256B) blob 2 ...
- wpf值转换器IValueConverter例子
转载:http://blog.163.com/wangzhenguo2005@126/blog/static/37140526201085113430862/ 值转换器可以把一种类型转换成另一种类型. ...
- 高效实用的.NET开源项目
似乎...很久很久没有写博客了,一直都想写两篇,但是却没有时间写.感觉最近有很多事情需要处理,一直都是疲于奔命,一直到最近才变得有些时间学习和充电.最近没有事情都会看一些博客和开源项目,发现介绍开源项 ...