poj 3468 A Simple Problem with Integers(线段树区间更新求和)
2015-10-31 10:28
579 查看
题目地址
题目大意:给出n长度的数组
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
解题思路:裸线段树区间更新并求和,注意用long long
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
typedef __int64 LL;
const int maxn = 100000+100;
struct Node
{
int l,r;
LL add,sum;
}tree[4*maxn];
int a[maxn];
void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].add = 0;
if(l == r)
{
tree[id].sum = a[l];
return;
}
int mid = (tree[id].l+tree[id].r)/2;
build(2*id,l,mid);
build(2*id+1,mid+1,r);
tree[id].sum = tree[id*2].sum+tree[id*2+1].sum;
}
void update(int id,int l,int r,LL c)
{
if(tree[id].l == l && tree[id].r == r)///区间对应
{
tree[id].add += c;
return;
}
tree[id].sum += LL(r-l+1)*c;
int mid = (tree[id].l+tree[id].r)/2;
if(r <= mid)
update(id*2,l,r,c);
else if(l >= mid+1)
update(id*2+1,l,r,c);
else
{
update(id*2,l,mid,c);
update(id*2+1,mid+1,r,c);
}
}
LL query(int id,int l,int r)///查询l到r区间的和
{
if(tree[id].l == l && tree[id].r == r)
return tree[id].sum+tree[id].add*(r-l+1);
if(tree[id].add)
{
tree[id*2].add += tree[id].add;
tree[id*2+1].add += tree[id].add;
tree[id].sum += LL(tree[id].r-tree[id].l+1)*tree[id].add;
tree[id].add = 0;
}
int mid = (tree[id].l+tree[id].r)/2;
if(r <= mid)
return query(id*2,l,r);
else if(l >= mid+1)
return query(id*2+1,l,r);
else
return query(id*2,l,mid)+query(id*2+1,mid+1,r);
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m) != EOF)
{
for(int i = 1; i <= n; i++)
scanf("%d\n",&a[i]);
build(1,1,n);
char ch[10];
int a,b,c;
for(int i = 1; i <= m; i++)
{
scanf("%s",ch);
if(ch[0] == 'Q')
{
scanf("%d%d", &a,&b);
printf("%I64d\n",query(1,a,b));
}
else
{
scanf("%d%d%d",&a,&b,&c);
update(1,a,b,c);
}
}
}
return 0;
}
题目大意:给出n长度的数组
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
解题思路:裸线段树区间更新并求和,注意用long long
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
typedef __int64 LL;
const int maxn = 100000+100;
struct Node
{
int l,r;
LL add,sum;
}tree[4*maxn];
int a[maxn];
void build(int id,int l,int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].add = 0;
if(l == r)
{
tree[id].sum = a[l];
return;
}
int mid = (tree[id].l+tree[id].r)/2;
build(2*id,l,mid);
build(2*id+1,mid+1,r);
tree[id].sum = tree[id*2].sum+tree[id*2+1].sum;
}
void update(int id,int l,int r,LL c)
{
if(tree[id].l == l && tree[id].r == r)///区间对应
{
tree[id].add += c;
return;
}
tree[id].sum += LL(r-l+1)*c;
int mid = (tree[id].l+tree[id].r)/2;
if(r <= mid)
update(id*2,l,r,c);
else if(l >= mid+1)
update(id*2+1,l,r,c);
else
{
update(id*2,l,mid,c);
update(id*2+1,mid+1,r,c);
}
}
LL query(int id,int l,int r)///查询l到r区间的和
{
if(tree[id].l == l && tree[id].r == r)
return tree[id].sum+tree[id].add*(r-l+1);
if(tree[id].add)
{
tree[id*2].add += tree[id].add;
tree[id*2+1].add += tree[id].add;
tree[id].sum += LL(tree[id].r-tree[id].l+1)*tree[id].add;
tree[id].add = 0;
}
int mid = (tree[id].l+tree[id].r)/2;
if(r <= mid)
return query(id*2,l,r);
else if(l >= mid+1)
return query(id*2+1,l,r);
else
return query(id*2,l,mid)+query(id*2+1,mid+1,r);
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m) != EOF)
{
for(int i = 1; i <= n; i++)
scanf("%d\n",&a[i]);
build(1,1,n);
char ch[10];
int a,b,c;
for(int i = 1; i <= m; i++)
{
scanf("%s",ch);
if(ch[0] == 'Q')
{
scanf("%d%d", &a,&b);
printf("%I64d\n",query(1,a,b));
}
else
{
scanf("%d%d%d",&a,&b,&c);
update(1,a,b,c);
}
}
}
return 0;
}
相关文章推荐
- C++函数返回值,你必须注意的问题
- IDEA快捷键使用技巧整理
- 吐槽一下最近遇到的一些交流上面的事情
- Mac OS 上设置 JAVA_HOME
- 断言(ASSERT)的用法
- Dom4j+PLSQL XML文件导入数据库
- 女人性冷淡深度原因
- 如何解决新浪微博返回结果中的中文编码问题
- Oracle之内存结构(SGA、PGA)
- Maven入门指南(一)
- 百度地图实现固定坐标点定位
- 2015.10月英语总结
- WordPress 插件机制的简单用法和原理(Hook 钩子)
- Android的BUG(一) - HTML 5 播放streaming video造成卡住的问题
- Hybrid--混合开发-文件上传包括android+服务器--3
- struts2多线程数据乱窜问题
- CEO 、 COO 、 CFO 、 CTO 、 CIO 是什么意思
- String.Join的巧用
- Java基础学习15 (子类对父类中方法的重写)
- dom4j读取xml