poj3468A Simple Problem with Integers(线段树,在段更新时要注意)
Description
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"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.
Output
You need to answer all Q commands in order. One answer in a line.
Sample Input
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
Sample Output
4
55
9
15
在段更新和查找时要注意,当父节点的下方和子节点的下方同时须要更新时不能直接覆盖了子节点的num,而是要加起来。
#include<iostream>
#include<stdio.h>
using namespace std;
#define N 100100
struct Tree
{
__int64 sum,num;//分别表示当前段的总和,子点的每个点所要加的值
bool b;//判断子节点是否要更新
}tree[4*N];
__int64 init[N+5];//初始时每个点的值
void builde(int l,int r,int k)
{
int m=(l+r)/2;
tree[k].b=false; tree[k].num=0;
if(l==r)
{
tree[k].sum=init[r]; return ;
}
builde(l,m,k*2);
builde(m+1,r,k*2+1);
tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
}
void set_child(int l,int r,int k)
{
int m=(l+r)/2;
if(tree[k*2].b==true)//注意这里,不能直接覆盖了
tree[k*2].num+=tree[k].num;
else
tree[k*2].num=tree[k].num;
tree[k*2].sum+=(m-l+1)*tree[k].num; if(tree[k*2+1].b==true)
tree[k*2+1].num+=tree[k].num;
else
tree[k*2+1].num=tree[k].num;
tree[k*2+1].sum+=(r-m)*tree[k].num;
tree[k*2].b=tree[k*2+1].b=true;
}
void updata(int l,int r,int k,int L,int R,__int64 num)
{
int m=(l+r)/2;
if(L<=l&&r<=R)
{
if(tree[k].b==true)
tree[k].num+=num;
else
tree[k].num=num;
tree[k].sum+=(r-l+1)*num;
tree[k].b=true;
return ;
}
if(tree[k].b==true)
set_child(l,r,k);
if(L<=m) updata(l,m,k*2,L,R,num);
if(R>m) updata(m+1,r,k*2+1,L,R,num);
tree[k].b=false;
tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
}
__int64 SUM;
void calculate(int l,int r,int k,int L,int R)
{
int m=(l+r)/2;
if(L<=l&&r<=R)
{
SUM+=tree[k].sum; return ;
}
if(tree[k].b==true)
set_child(l,r,k);
if(L<=m) calculate(l,m,k*2,L,R);
if(R>m) calculate(m+1,r,k*2+1,L,R);
tree[k].b=false;
}
int main()
{
int n,m,L,R,i;
__int64 num;
char ch[2];
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%I64d",&init[i]);
getchar();
builde(1,n,1);
while(m--)
{
scanf("%s%d%d",ch,&L,&R);
if(ch[0]=='Q')
{
SUM=0; calculate(1,n,1,L,R);
printf("%I64d\n",SUM);
}
else
{
scanf("%I64d",&num);
updata(1,n,1,L,R,num);
}
}
}
poj3468A Simple Problem with Integers(线段树,在段更新时要注意)的更多相关文章
- POJ3468_A Simple Problem with Integers(线段树/成段更新)
解题报告 题意: 略 思路: 线段树成段更新,区间求和. #include <iostream> #include <cstring> #include <cstdio& ...
- 【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记
A Simple Problem with Integers Time Limit:5000MS Memory Limit:131072K Case Time Limit:2000MS Descr ...
- POJ 3468 A Simple Problem with Integers (线段树成段更新)
题目链接:http://poj.org/problem?id=3468 题意就是给你一组数据,成段累加,成段查询. 很久之前做的,复习了一下成段更新,就是在单点更新基础上多了一个懒惰标记变量.upda ...
- POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)
A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...
- A Simple Problem with Integers(线段树,区间更新)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 83822 ...
- 2018 ACMICPC上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节)
2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节) 链接:https://ac.nowcoder.co ...
- poj3468 A Simple Problem with Integers (线段树区间最大值)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 92127 ...
- POJ3648 A Simple Problem with Integers(线段树之成段更新。入门题)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 53169 Acc ...
- poj 3468 A Simple Problem with Integers 线段树第一次 + 讲解
A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal w ...
随机推荐
- 学习java之泛型类和泛型方法
上一篇博文中我自己试着用了下泛型类,昨天看java编程思想一书,发现里面有这么一段话: 使用参数化方法而不是用参数化类的方便之处在于:你不必为需要应用的每种不同类型都使用一个参数去实例化这个类,并且你 ...
- (转)每天一个Linux命令(6):mv
mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 1.命令格式: mv [选项] 源文件或目 ...
- ecshop init.php文件分析(转)
<?php /** * ECSHOP 前台公用文件 */ //防止非法调用 defined-判断常量是否已定义,如果没返回false if (!defined('IN_ECS')) { die( ...
- 关于Latent Dirichlet Allocation
今天,也没出去,晚上宿舍没有人,自己思考了下人生,毕设还是大事,觉得现在有必要把LDA从前往后彻彻底底的读一遍了,因为现在的感觉就是什么都知道一点皮毛,但是理解的都不深,LDA好像(恩,相当不好)现在 ...
- [转载] FFMpeg的码率控制
mediaxyz是一位研究ffmpeg有三年的高人了,这几天一直在折腾ffmpeg中的x264,就是不知道该如何控制码率,主要是参数太多,也不知道该如何设置,在google上search了一下,这方面 ...
- mysql 1130 ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to connect to this MySQL server
mysql -u root -p mysql;use mysql; mysql;select 'host' from user where user='root'; mysql;update u ...
- Free Candies
题意: 有4堆东西,每堆有n个每个有一个颜色,现在有一个篮子最多能装5个不同的颜色的东西,每次都从堆顶拿,当篮子出现两个相同颜色,可以获得这两个东西,求获得的最大数量 分析: 因为就4推,可以把各堆的 ...
- Linux基本命令(8)网络操作的命令
网络操作命令 命令 功能 命令 功能 ftp 传送文件 telnet 远端登陆 bye 结束连线并结束程序 rlogin 远端登入 ping 检测主机 netstat 显示网络状态 8.1 ftp命令 ...
- 给编译好的DLL增加签名
两个步骤,记录如下,主要用在silverlight中引用的dll要签名时: "C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\ildasm ...
- Spring依赖注入 --- 简单使用说明
Spring依赖注入 --- 简单使用说明 本文将对spring依赖注入的使用做简单的说明,enjoy your time! 1.使用Spring提供的依赖注入 对spring依赖注入的实现方法感兴趣 ...