您的位置:首页 > 其它

POJ 3468 A Simple Problem with Integers(线段树,延迟标记)

2017-11-03 14:55 399 查看
题目:http://poj.org/problem?id=3468

大意:Q是查询,C 3 6 3是3到6加3,一个简单的线段树:

这就是我写线段树的风格了,我不管,这就是最帅的。


(结果写成 ll即可,以后最好都写成 ll ,防止乱了)

#include<cstdio>
#include<algorithm>
#include<iostream>
#define ll long long
using namespace std;
const int maxn = 111111;
ll num[maxn<<2];
struct Tree{
int l,r;
ll sum;
}tree[maxn<<2];

ll lazy[maxn<<2];
void down(int t, int len){
if(lazy[t]){
lazy[t<<1] += lazy[t];
lazy[t<<1|1] += lazy[t];/*延迟标记往下传*/
tree[t<<1].sum += lazy[t] * (len-(len>>1));/*左子树比右子树多1*/
tree[t<<1|1].sum += lazy[t] * (len>>1);
lazy[t] = 0; /*往下传完就赋0*/
}
}

void build(int l,int r,int t){
tree[t].l=l; tree[t].r=r;
lazy[t]=0;
if(l==r){
tree[t].sum=num[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,t<<1);
build(mid+1,r,t<<1|1);
tree[t].sum=tree[2*t].sum+tree[2*t+1].sum;
}
void update(int x,int l,int r,int t){
if(l<=tree[t].l&&r>=tree[t].r){
lazy[t]+=x;
tree[t].sum+=(ll)x*(tree[t].r-tree[t].l+1);
//printf("t=%d c=%d sum=%d",t,x,tree[t].sum);
return;
}
//printf("t=%d %d %d",t,tree[t].l,tree[t].r);
down(t,tree[t].r-tree[t].l+1);
int mid=(tree[t].l+tree[t].r)>>1;
if(l<=mid) update(x,l,r,t<<1);
if(r>mid) update(x,l,r,t<<1|1);
tree[t].sum=tree[2*t].sum+tree[2*t+1].sum;
}
ll query(int l,int r,int t){
if(l<=tree[t].l&&r>=tree[t].r) return tree[t].sum;
down(t,tree[t].r-tree[t].l+1);
int mid=(tree[t].l+tree[t].r)>>1; ll ans=0;
if(l<=mid) ans+=query(l,r,2*t);/*加完左边加上右边的,不用分情况考虑*/
if(r>mid) ans+=query(l,r,2*t+1);
return ans;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&num[i]);
build(1,n,1);
while(m--){
char ss[3];
int l,r,val;
scanf("%s",ss);
if(ss[0]=='Q'){
scanf("%d%d",&l,&r);
printf("%lld\n",query(l,r,1));
}
else{
scanf("%d%d%d",&l,&r,&val);
update(val,l,r,1);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐