POJ 3468 A Simple Problem with Integers(线段树)

题目链接

题意 : 给你n个数,进行两种操作,第一种是将a到b上所有元素都加上c,第二种是查询a到b上所有元素之和输出。

思路 : 线段树,以前写过博客,但是现在在重刷,风格改变,,所以重新写一篇。。。。

 #include <cstdio>
#include <cstring>
#include <iostream>
#define LL long long
using namespace std ; LL lz[*],p[*] ; void pushup(int rt)
{
p[rt] = p[rt << ] + p[rt << | ] ;
}
void pushdown(int rt,int m)
{
if(lz[rt])
{
lz[rt << ] += lz[rt] ;
lz[rt << | ] += lz[rt] ;
p[rt << ] += (m-m/)*lz[rt] ;
p[rt << | ] += m/ * lz[rt] ;
lz[rt] = ;
}
}
void build(int l,int r,int rt)
{
lz[rt] = ;
if(l == r)
{
scanf("%I64d%*c",&p[rt]) ;
return ;
}
int mid = (l+r) >> ;
build(l,mid,rt << ) ;
build(mid+,r,rt << | ) ;
pushup(rt) ;
}
LL query(int L,int R,int l,int r,int rt)
{
LL sum = ;
if(l >= L && R >= r)
{
return p[rt] ;
}
pushdown(rt,r-l+) ;
int mid = (l+r) >> ;
if(mid >= L)
sum += query(L,R,l,mid,rt << ) ;
if(mid < R)
sum += query(L,R,mid+,r,rt << | ) ;
return sum ;
}
void update(int L,int R, int l,int r,int sc,int rt)
{
if(l >= L && r <= R)
{
lz[rt] += sc ;
p[rt] += (r-l+)*sc ;
return ;
}
pushdown(rt,r-l+) ;
int mid = (l+r) >> ;
if(mid >= L)
update(L,R,l,mid,sc,rt << ) ;
if(mid < R)
update(L,R,mid+,r,sc,rt << | ) ;
pushup(rt) ;
}
int main()
{
int N,Q ,a,b;
LL c ;
char ch[] ;
while(~scanf("%d %d",&N,&Q))
{
build(,N,) ;
for(int i = ; i < Q ; i++)
{
scanf("%s",ch) ;
if(ch[] == 'Q')
{
scanf("%d %d",&a,&b) ;
LL sum = query(a,b,,N,) ;
printf("%I64d\n",sum) ;
}
else
{
scanf("%d %d %I64d",&a,&b,&c) ;
update(a,b,,N,c,) ;
}
}
}
return ;
}
上一篇:SQL Server查看库、表占用空间大小


下一篇:iOS 使用interface builder 创建太复杂的constrains时容易产生crash