您的位置:首页 > 其它

Luogu-P3372 (Lazy_tag 线段树模板)

2017-04-26 21:42 399 查看

题目

链接:https://www.luogu.org/problem/show?pid=3372

就是个区间修改(都增加某个值),区间查询的简单线段树模板

分析



程序中线段树用了个结构体封装了起来,存起来。打网络赛时可以复制下来,依题意稍作修改就能用了。

程序

#include <cstdio>
#define INF 100005
int n,m,du,k,k1,k2,k3;

struct segment_tree{
#define X tr[x]
#define lx (x<<1)
#define rx ((x<<1)+1)
#define L tr[lx]
#define R tr[rx]
#define Mid (l+r>>1)
#define sz(x) (X.r-X.l+1)
struct node{long long l,r,s,t1;} tr[4*INF];

long long mer(int x,int y){return tr[x].s+tr[y].s;}

void bui(int x,int l,int r){
if (l==r) {X=(node){l,r
4000
,(scanf("%d",&du),du),0}; return;}
bui(lx,l,Mid);
bui(rx,Mid+1,r);
X=(node){l,r,mer(lx,rx),0};
}

void addtag(int x,int v){
X.s+=v*sz(x);
X.t1+=v;
}
void Down(int x){
if (X.t1!=0){
addtag(lx,X.t1);
addtag(rx,X.t1);
X.t1=0;
}
}

void add(int x,int l,int r,int v){
if (l<=X.l && X.r<=r){addtag(x,v); return;}
Down(x);
if (l<=L.r) add(lx,l,r,v);
if (R.l<=r) add(rx,l,r,v);
X.s=mer(lx,rx);
}

long long que(int x,int l,int r){
if (l<=X.l && X.r<=r) return X.s;
Down(x);
long long ret=0;
if (l<=L.r) ret+=que(lx,l,r);
if (R.l<=r) ret+=que(rx,l,r);
return ret;
}
}tree;

int main(){
scanf("%d%d",&n,&m);
tree.bui(1,1,n);
while (m-- && scanf("%d",&k)){
if (k==1){
scanf("%d%d%d",&k1,&k2,&k3);
tree.add(1,k1,k2,k3);
}
if (k==2){
scanf("%d%d",&k1,&k2);
printf("%lld\n",tree.que(1,k1,k2));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: