【线段树成段更新成段查询模板】【POJ3468】A Simple Problem with Integerst
题目大意:
2个操作
A.区间a b 增加 c
B 查询a b;
注意事项:1.记住要清除标记
2.查询时要下放标记,但没必要向上更新
线段:自带的,不用建模
区间和性质:sum;
/*
WA 1次 以为不要LONG LONG
*/
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#define oo 0x13131313
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
const int maxn=100000+5;
using namespace std;
int N,Q;
LL tree[maxn*4];
LL col[maxn*4];
void PushUp(int rt)
{
tree[rt]=tree[rt<<1]+tree[rt<<1|1];
}
int build(int l,int r,int rt)
{
col[rt]=0;
if(l==r){scanf("%lld",&tree[rt]);return 0;}
int m=(l+r)>>1;
build(lson);
build(rson);
PushUp(rt);
}
void Pushdown(int rt,int k) //k是长度
{
if(col[rt])
{
col[rt<<1]+=col[rt];
col[rt<<1|1]+=col[rt];
tree[rt<<1]+=(k-(k>>1))*col[rt];
tree[rt<<1|1]+=(k>>1)*col[rt];
col[rt]=0;
}
}
int update(int L,int R,int c,int l,int r,int rt) {
if (L<=l&&r<= R) {
col[rt]+=c; //不同题目处理方式不同 ,
tree[rt]+=(LL)c*(r-l+1);
return 0;
}
Pushdown(rt,r-l+1); //Lazy 下放
int m=(l+r)>>1; //下面与以往一样
if (L<=m) update(L,R,c,lson);
if (R>m) update(L,R,c,rson);
PushUp(rt);
}
LL query(int L,int R,int l,int r,int rt)
{
LL temp=0;
if(L<=l&&r<=R){return tree[rt];}
Pushdown(rt,r-l+1);
int m=(l+r)>>1;
if(L<=m) temp+=query(L,R,lson);
if(R>m) temp+=query(L,R,rson);
return temp;
}
void solve()
{
char temp;
int a,b,c;
getchar();
for(int i=1;i<=Q;i++)
{
scanf("%c",&temp);
if(temp=='Q')
{
scanf("%d%d",&a,&b);
printf("%lld\n",query(a,b,1,N,1));
}
else if(temp=='C')
{
scanf("%d%d%d",&a,&b,&c);
update(a,b,c,1,N,1);
}
getchar();
}
}
void init()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
}
int main()
{
// init();
while(cin>>N>>Q)
{
build(1,N,1);
solve();
}
return 0;
}
全long long 形式
/*
WA 1次 以为不要LONG LONG
WA 2次 全LONG LONG为妙
WA 3次 m 忘记改成long long 了
*/
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#define oo 0x13131313
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
const int maxn=100000+5;
using namespace std;
int N,Q;
LL tree[maxn*4];
LL col[maxn*4];
void PushUp(int rt)
{
tree[rt]=tree[rt<<1]+tree[rt<<1|1];
}
int build(LL l,LL r,int rt)
{
col[rt]=0;
if(l==r){scanf("%lld",&tree[rt]);return 0;}
LL m=(l+r)>>1;
build(lson);
build(rson);
PushUp(rt);
}
void Pushdown(int rt,LL k) //k是长度
{
if(col[rt])
{
col[rt<<1]+=col[rt];
col[rt<<1|1]+=col[rt];
tree[rt<<1]+=(k-(k>>1))*col[rt];
tree[rt<<1|1]+=(k>>1)*col[rt];
col[rt]=0;
}
}
int update(int L,int R,LL c,LL l,LL r,int rt) {
if (L<=l&&r<= R) {
col[rt]+=c; //不同题目处理方式不同 ,
tree[rt]+=c*(r-l+1);
return 0;
}
Pushdown(rt,r-l+1); //Lazy 下放
LL m=(l+r)>>1; //下面与以往一样
if (L<=m) update(L,R,c,lson);
if (R>m) update(L,R,c,rson);
PushUp(rt);
}
LL query(int L,int R,LL l,LL r,int rt)
{
LL temp=0;
if(L<=l&&r<=R){return tree[rt];}
Pushdown(rt,r-l+1);
LL m=(l+r)>>1;
if(L<=m) temp+=query(L,R,lson);
if(R>m) temp+=query(L,R,rson);
return temp;
}
void solve()
{
char temp;
LL a,b;
LL c;
getchar();
for(int i=1;i<=Q;i++)
{
scanf("%c",&temp);
if(temp=='Q')
{
scanf("%lld%lld",&a,&b);
printf("%d\n",query(a,b,1,N,1));
}
else if(temp=='C')
{
scanf("%lld%lld%lld",&a,&b,&c);
update(a,b,c,1,N,1);
}
getchar();
}
}
void init()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
}
int main()
{
// init();
while(cin>>N>>Q)
{
build(1,N,1);
solve();
}
return 0;
}
【线段树成段更新成段查询模板】【POJ3468】A Simple Problem with Integerst的更多相关文章
- hdu3308LCIS(线段树,点更新,段查寻,查寻时一定要注意跨越时如何计算)
Problem Description Given n integers. You have two operations: U A B: replace the Ath number by B. ( ...
- 线段树 (区间更新,区间查询) poj http://poj.org/problem?id=3468
题目链接 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...
- 线段树---poj3468 A Simple Problem with Integers:成段增减:区间求和
poj3468 A Simple Problem with Integers 题意:O(-1) 思路:O(-1) 线段树功能:update:成段增减 query:区间求和 Sample Input 1 ...
- poj3468A Simple Problem with Integers(线段树的区域更新)
http://poj.org/problem?id=3468 真心觉得这题坑死我了,一直错,怎么改也没戏,最后tjj把q[rt].lz改成了long long 就对了,真心坑啊. 线段树的区域更新. ...
- hdu 1556:Color the ball(线段树,区间更新,经典题)
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- hdu 1698:Just a Hook(线段树,区间更新)
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- UVA 12436-Rip Van Winkle's Code(线段树的区间更新)
题意: long long data[250001]; void A( int st, int nd ) { for( int i = st; i \le nd; i++ ) data[i] = da ...
- hdu1698线段树的区间更新区间查询
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- hdu1754线段树的单点更新区间查询
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- HDUOJ---1754 I Hate It (线段树之单点更新查区间最大值)
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
随机推荐
- lastcomm搜索并显示以前执行过的命令信息
lastcomm搜索并显示以前执行过的命令信息
- C语言的本质(14)——不完全类型和复杂声明
ISO 将 C 的类型分为三个不同的集合: 函数.对象和不完全类型三大类.函数类型很明显:对象类型包含其他一切,除非不知道对象的大小.该标准使用术语"对象类型"指定指派的对象必须具 ...
- C++类对应的内存结构
提示1:对“内存结构”表示有疑问或不解的,先参考: http://blog.csdn.net/guogangj/archive/2007/05/25/1625199.aspx, 本文使用的表示方法和V ...
- OpenSuSE zypper repo及Desktop媒体播放器设置 for OpenSuSE12.
1.禁用官方源和DVD光盘源,启用中国大陆源 使用DVD光盘安装好openSUSE 12.2之后,软件安装源中默认存在一个名称为”openSUSE-12.2-1.6″的软件源,这个源的URL实际上是指 ...
- docker学习笔记(1)
(1)Docker介绍 关于Docker的介绍,我就不列举出来了.到百度.谷歌搜索.非常多介绍文章.以下我给出官网的介绍:https://www.docker.com/whatisdocker/ (2 ...
- 如何灵活利用免费开源图标字体-IcoMoon篇
http://www.zhangxinxu.com/wordpress/2012/06/free-icon-font-usage-icomoon/
- VB.NET 内存指针和非托管内存的应用
介绍 Visual Basic 从来不像在C或C++里一样灵活的操纵指针和原始内存.然而利用.NET框架中的structures 和 classes,可以做许多类似的事情.它们包括 IntPtr, ...
- javascript中数组方法小计
一:数组的常用方法: 1:join(); 将数组转为字符串显示.不输入参数,默认以逗号连接:输入参数,则以参数连接. var arr=[1,2,3]; console.log(arr.join()); ...
- PHP简易计算器方法2
<?php $sum=""; $num1=$_POST['num1']; $num2=$_POST['num2']; if(is_numeric($num1 ...
- Linux 计算某文件夹下的所有文件的md5值
使用find 命令 find /root -type f -print0 |xargs -0 md5sum >a.md5 校验的话 md5sum -c a.md5