POJ 3468 A Simple Problem with Integers 【树状数组】
题目链接: id=3468">http://poj.org/problem?id=3468
题目大意:给出一组数组v[i],有两种操作,一种给出两个数a,b。要求输出v[a]到v[b]之间的和。还有一种给出三个数a,b,c,让v[a]到v[b]之间的数全都加上c。
全然是树状数组可以实现的功能,可是假设就这样单纯的套用模板,做另外一种操作是更新每一个值,这种操作就有可能超时。
换一种思路,既然另外一种操作是给某区间上的全部数加上同样的值,那么应该是可以简化的才对。
如果数组sum[i]为原数组从v[1]到v[i]的和。数组c1[i]为更新之后,v[i]到v[n]的添加量。分析一下结果ans:
a,b之间的和ans=sum[b]-sum[a-1]+c1[1]*x + c1[2]*(x-1) + c1[3]*(x-2)+...+c1[x]*1
ans=sum[b]-sum[a-1]+segema(c1[i]*(x-i+1))
ans=sum[b]-sum[a-1] + (x+1)*segma(c1[i]) - segma(c1[i]*i)
令c2[i]=c1[i]*i;
如此便能利用树状数组解出此题
代码:
#include <stdio.h>
#define N 100001
#define lowbit(i) ( i & (-i) )
int n;
__int64 v[N];
__int64 c1[N];// 每一个C数组代表v[i-lowbit(i)+1]到v[i]之间的和
__int64 c2[N];
__int64 sum[N]; void Updata(__int64 *array,__int64 i,__int64 a)
{
for(;i<=n;i+=lowbit(i))
array[i]+=a;
}
__int64 Sumv(__int64 *array,__int64 i) //求出数组v[1]到v[i]的和
{
__int64 result=0;
while (i>=1)
{
result+=array[i];
i-=lowbit(i);
}
return result;
}
int main()
{
__int64 q,i=0;
__int64 ans=0;
scanf("%I64d%I64d",&n,&q);
for(i=1;i<=n;i++)
scanf("%I64d",&v[i]);
for(__int64 i=1;i<=n;i++)
sum[i]=sum[i-1]+v[i];
while(q--)
{
char ch[2];
scanf("%s",ch);
if(ch[0]=='Q')
{
__int64 s,t;
scanf("%I64d%I64d",&s,&t);
ans=sum[t]-sum[s-1];
ans+=((t+1)*Sumv(c1,t)-Sumv(c2,t));
ans-=(s*Sumv(c1,s-1)-Sumv(c2,s-1));
printf("%I64d\n",ans);
}
else
{
__int64 a,b,c;
scanf("%I64d%I64d%I64d",&a,&b,&c);
Updata(c1,a,c);
Updata(c1,b+1,-c);
Updata(c2,a,c*a);
Updata(c2,b+1,-c*(b+1));
}
}
return 0;
}
POJ 3468 A Simple Problem with Integers 【树状数组】的更多相关文章
- A Simple Problem with Integers(树状数组HDU4267)
A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (J ...
- HDU 4267 A Simple Problem with Integers --树状数组
题意:给一个序列,操作1:给区间[a,b]中(i-a)%k==0的位置 i 的值都加上val 操作2:查询 i 位置的值 解法:树状数组记录更新值. 由 (i-a)%k == 0 得知 i%k == ...
- POJ3468 A Simple Problem With Integers 树状数组 区间更新区间询问
今天学了很多关于树状数组的技巧.一个是利用树状数组可以简单的实现段更新,点询问(二维的段更新点询问也可以),每次修改只需要修改2个角或者4个角就可以了,另外一个技巧就是这题,原本用线段树做,现在可以用 ...
- 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 ...
- poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和
A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...
随机推荐
- arcgis连接excel出现数据库失败 外部数据库驱动程序意外错误
微软搞事情,删除以下更新就行:win7 KB4041678 KB4041681SERVER 2008 R2 KB4041678 KB4041681WIN10 KB4041676 KB4041691SE ...
- std::vector利用swap()函数进行内存的释放【转】
首先,vector与deque不同,其内存占用空间只会增长,不会减小.比如你首先分配了10,000个字节,然后erase掉后面9,999个,则虽然有效元素只有一个,但是内存占用仍为10,000个.所有 ...
- SQL Server中的database checkpoint
基于性能方面的考虑, 数据库引擎会在内存(buffer cache)中执行数据库数据页(pages)的修改, 不会再每次做完修改之后都把修改了的page写回到磁盘上. 更准确的说, 数据库引擎定期在每 ...
- AngularJs 阻止事件运行,防止冒泡穿透事件
ng-click 低啊用方法后 添加语句$event.stopPropagation(); <button type="button" ng-click="doSo ...
- c++call back
#include "stdafx.h" struct A; typedef void(A::*MemFuncPtr) (int* e); class A { int a; }; c ...
- 使用ViewDragHelper打造属于自己的DragLayout(抽屉开关 )
使用ViewDragHelper打造属于自己的DragLayout(抽屉开关 ) DrawLayout这个自己定义的空间非经常见.qq,网易新闻.知乎等等,都有这样的效果,那这样的效果是如何实现的呢? ...
- go语言知识点
1.make()只是用3种内建的引用类型:切片.map和channel.new函数分配内存,make函数初始化. 2.:=只能使用在函数内部.
- 基于Java spring框架的微信企业号开发中关于js-sdk的配置
在调用js-sdk的第一步,我们需要引入js-sdk的js链接,然后执行wx.config,官方示例如下所示: wx.config({ debug: true, // 开启调试模式,调用的所有api的 ...
- Foreda8上安装CMake2.8.1.2
本机操作系统:Linux 2.6.23.1-42.fc8 #1 SMP Tue Oct 30 13:55:12 EDT 2007 i686 i686 i386 GNU/Linux 在本机上准备安装My ...
- Office EXCEL VBA如何取得EXCEL中的行数和列数
VBA取得EXCEL表格中的行数和列数 请注意不要使用Columus等关键字作为变量,例如"Columus = ActiveSheet.UsedRange.Columns.Count&quo ...