P3372【模板】线段树 1
1.将某区间每一个数加上x
2.求出某区间每一个数的和
#include<bits/stdc++.h>
using namespace std;
#define MAX 100005
#define ll long long
#define inf 0x3f3f3f
int num[MAX];
struct node{
ll val;
ll add;
}segtree[(MAX<<2)+5];
void build(int root,int nl,int nr){
segtree[root].add=0;
if(nl==nr){
segtree[root].val=num[nl];
return ;
}
int mid=nl+nr>>1;
build(root<<1,nl,mid);
build(root<<1|1,mid+1,nr);
segtree[root].val=segtree[root<<1].val+segtree[root<<1|1].val;//?update???
}
void pushdown(int root,int nl,int nr){
if(segtree[root].add){
int mid = nr+nl>>1;
segtree[root<<1].val+=(segtree[root].add)*(mid-nl+1);
segtree[root<<1|1].val+=segtree[root].add*(nr-mid);
segtree[root<<1].add+=segtree[root].add;
segtree[root<<1|1].add+=segtree[root].add;
segtree[root].add=0;
}
}
ll query(int root,int nl,int nr,int ql,int qr){
if(nl>qr||nr<ql){
return 0;
}
if(nl>=ql&&nr<=qr){
return segtree[root].val;
}
pushdown(root,nl,nr);
int mid=nl+nr>>1;
return query(root<<1,nl,mid,ql,qr)+query(root<<1|1,mid+1,nr,ql,qr);
}
void update(int root,int nl,int nr,int ql,int qr,int add){
if(nl>qr||nr<ql){
return ;
}
if(nl>=ql&&nr<=qr){
segtree[root].val+=(nr-nl+1)*add;
segtree[root].add+=add;
return ;
}
if(nl==nr){
segtree[root].val+=add;
return ;
}
pushdown(root,nl,nr);
int mid=nl+nr>>1;
update(root<<1,nl,mid,ql,qr,add);
update(root<<1|1,mid+1,nr,ql,qr,add);
segtree[root].val=segtree[root<<1].val+segtree[root<<1|1].val;//?build???
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
}
build(1,1,n);
for(int i=1;i<=m;i++){
int a;
scanf("%d",&a);
if(a==1){
int b,c,d;
scanf("%d%d%d",&b,&c,&d);
update(1,1,n,b,c,d);
}
else {
int b,c;
scanf("%d%d",&b,&c);
printf("%lld\n",query(1,1,n,b,c));
}
}
return 0;
}
HDU-1166
#include<bits/stdc++.h>
using namespace std;
#define MAX 50005
int a[MAX];
struct node{
int val;
int add;
}segtree[(MAX<<2)+5];
void build(int root,int l,int r){
segtree[root].add=0;
if(l==r){
segtree[root].val=a[l];
return ;
}
int mid=l+r>>1;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
segtree[root].val=segtree[root<<1].val+segtree[root<<1|1].val;
}
void pushdown(int root,int l,int r){
if(segtree[root].add){
int mid=l+r>>1;
segtree[root<<1].val+=segtree[root].add*(mid+1-l);
segtree[root<<1|1].val+=segtree[root].add*(r-mid);
segtree[root<<1].add+=segtree[root].add;
segtree[root<<1|1].add+=segtree[root].add;
segtree[root].add=0;
}
}
int query(int root,int l,int r,int ql,int qr){
if(l>qr||r<ql)return 0;
if(l>=ql&&r<=qr)return segtree[root].val;
pushdown(root,l,r);
int mid=l+r>>1;
return query(root<<1,l,mid,ql,qr)+query(root<<1|1,mid+1,r,ql,qr);
}
void update(int root,int l,int r,int ql,int qr,int delta){
if(l>qr||r<ql)return ;
if(l>=ql&&r<=qr){
segtree[root].add=delta;
segtree[root].val+=(r-l+1)*delta;
return ;
}
if(l==r){
segtree[root].val+=delta;
return ;
}
pushdown(root,l,r);
int mid=l+r>>1;
update(root<<1,l,mid,ql,qr,delta);
update(root<<1|1,mid+1,r,ql,qr,delta);
segtree[root].val=segtree[root<<1].val+segtree[root<<1|1].val;
}
int main(){
int pa;
cin>>pa;
int cnt=0;
while(pa--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
printf("Case %d:\n",++cnt);
build(1,1,n);
char cmd[10];
while(scanf("%s",cmd),strcmp(cmd,"End")){
int a,b;
scanf("%d%d",&a,&b);
if(strcmp(cmd,"Query")==0)printf("%d\n",query(1,1,n,a,b));
else if(strcmp(cmd,"Add")==0)update(1,1,n,a,a,b);
else if(strcmp(cmd,"Sub")==0)update(1,1,n,a,a,-b);
}
}
return 0;
}