poj 3468: A Simple Problem with Integers (树状数组区间更新)
题目链接: http://poj.org/problem?id=3468
题目是对一个数组,支持两种操作
操作C:对下标从a到b的每个元素,值增加c;
操作Q:对求下标从a到b的元素值之和。
这道题也可以用线段树解,本文不做描述,下面分析如何用树状数组来解决这道题。
/*先把问题简化一点,因为 结果=初值+增量,所以,我们可以只对增量进行分析。然后,这种题有一个特点,就是如果对一般的一个操作C与操作查询前缀和的组合符合条件,那么无论进行多少次任意操作结果都是正确的。故 假设,先进行一次参数分别为 l,r,c 的操作C,再进行一次查询前缀和Si的操作(i 与l r的大小关系不定)。操作C之后,对Si,①当i<l时,Si=0,②当l<=i<r时,Si=c*(i-l+1),③当i>=r时,Si=c*(r-l+1)。要使情况①③满足比较简单,只需使add操作不在l左边进行,且对一树状数组的l和r分别进行+x+c*(r-l+1),-x的操作;而分析如何满足情况②,可以把Si看作是分布在直线y=c(x-l)=cx-cl上的一系列散点,易看出实现+cx的方法,就是在l执行add c的操作,在r执行add -c的操作,查询时查询sum()*x,而实现-cl的方法可以与上面“分别进行+x+c*(r-l+1),-x的操作”(引号中的x是不确定的)联系起来得出。故而任意Si都可以得出。*/
#include <cstdio> typedef long long LL; const int maxn =1e5+;
LL a[][maxn];
LL psum[maxn];
int n; inline int lowbit(int x)
{
return x&-x;
}
void add(LL a[],int x,int d)
{
while(x<=n)
{
a[x]+=d;
x+=lowbit(x);
}
}
LL sum(LL a[],int x)
{
LL ret=;
while(x)
{
ret+=a[x];
x-=lowbit(x);
}
return ret;
} LL query(int x)
{
return sum(a[],x)*x+sum(a[],x);
} int main()
{
int q;
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
{
scanf("%I64d",&psum[i]);
psum[i]+=psum[i-];
}
char op[];
while(q--)
{
int l,r;
scanf("%s%d%d",op,&l,&r);
if(op[]=='Q')
printf("%I64d\n",query(r)-query(l-)+psum[r]-psum[l-]);
else
{
int c;
scanf("%d",&c);
add(a[],l,c);
add(a[],r,-c);
add(a[],l,c*(-l+));
add(a[],r,c*r);
}
}
}
//上面内容废弃,以下解析为2018.05.30更新
假设数组用a[]表示,定义辅助数组s[]、d[],其具体含义为
且s[]、d[]间有如下关系
原题中对a[]的区间修改,可以视为对d[]的单点修改,而s[]又可以由d[i]、i*d[i]的前缀和推导出来。且维护s1[]、s2[]较容易,因为每次操作都是对d[]进行单点修改。具体可以参考以下代码
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
typedef long long LL; const int N=1e5+; LL s1[N],s2[N];
int n,q; inline int lowbit(int x)
{
return x&-x;
}
void add(LL a[],int i,LL x)
{
while(i<=n)
{
a[i]+=x;
i+=lowbit(i);
}
}
LL sum(LL a[],int i)
{
LL ret=;
while(i)
{
ret+=a[i];
i-=lowbit(i);
}
return ret;
}
void Add(int i,LL x)
{
add(s1,i,x*i),add(s2,i,x);
}
LL Sum(int i)
{
return -sum(s1,i)+(i+)*sum(s2,i);
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
{
LL t;
scanf("%lld",&t);
Add(i,t),Add(i+,-t);
}
while(q--)
{
int l,r;
char op[];
scanf("%s%d%d",op,&l,&r);
if(op[]=='Q')
printf("%lld\n",Sum(r)-Sum(l-));
else
{
LL t;
scanf("%lld",&t);
Add(l,t),Add(r+,-t);
}
}
}
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 ...
随机推荐
- (转)用Flink取代Spark Streaming!知乎实时数仓架构演进
转:https://mp.weixin.qq.com/s/e8lsGyl8oVtfg6HhXyIe4A AI 前线导读:“数据智能” (Data Intelligence) 有一个必须且基础的环节,就 ...
- vue2.X 与 vue1.X 的区别
vue2.0: bower info vue http://vuejs.org/ 到了2.0以后,有哪些变化? 1. 在每个组件模板,不在支持片段代码 组件中模板: 之前: <template& ...
- nginx用途
Nginx常用来做静态内容服务器和代理服务器,用来放置静态资源或者转发请求给后面的应用服务. 1. Nginx作为静态服务器使用 作为一个Web服务器,其最主要的任务是作为静态服务器使用. 你需要将 ...
- Mac定制终端:iTerm2 + zsh + powerline
原始界面: 配置后的界面: 安装iTerm2 可以直接去官网下载:https://www.iterm2.com/ 下载后直接安装即可 安装主题 所有主题:https://iterm2color ...
- Python笔记(十七)_面向对象编程
面向对象编程 概念:简称OOP,是一种程序设计思想:OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数 面向对象的设计思想:抽象出类class,根据类class创建实例对象instan ...
- pandas dataframe 一行变多行 (query pv统计term pv)
关键字: 用jieba切词 用expand 一列变多列 用stack 列转行 用group by + aggr 相同term的pv求和 上效果: query pv 今日新鲜事 今日头条 北京天气 上海 ...
- “希希敬敬对”Alpha版本发布说明
Alpha版本的所有功能如下: 1.完成根据贴吧关键字检索的功能,通过用户输入的关键词或URL地址链接到对应的贴吧页面,并爬取到该贴吧前10页的相关数据.2.对爬取到的数据进行分析和整合,实现获取该贴 ...
- 《JAVA设计模式》之原型模式(Prototype)
在阎宏博士的<JAVA与模式>一书中开头是这样描述原型(Prototype)模式的: 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办 ...
- [BZOJ 4771]七彩树(可持久化线段树+树上差分)
[BZOJ 4771]七彩树(可持久化线段树+树上差分) 题面 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i] ...
- Codeforces 1091C (数学)
题面 传送门 分析 假设k是固定的,那访问到的节点编号就是\(1+(a·k \mod n )\),其中a为正整数. 通过找规律不难发现会出现循环. 通过题目中的图片我们不难发现 只有k=1,2,3,6 ...