洛谷 P3372 线段树1
作者:互联网
这是一道模板题
线段树介绍https://www.cnblogs.com/nvwang123/p/10420832.html
1 #include<bits/stdc++.h> 2 using namespace std; 3 int m,n; 4 int a[100001]; 5 6 struct node{ 7 int l,r; 8 long long w,f; //w是区间值,f是懒标记 9 }xds[4*100001]; //4倍空间 10 11 //一、建树 12 void buid(int l,int r,int k){ 13 xds[k].l=l; 14 xds[k].r=r; 15 if(l==r){ 16 xds[k].w=a[l]; // 最底层的区间从左边开始是1,所以可以这样 17 return; 18 } 19 int m=(l+r)/2; 20 buid(l,m,2*k); 21 buid(m+1,r,2*k+1); 22 xds[k].w=xds[2*k].w+xds[2*k+1].w;//不要忘记区间和上传!!特别容易忘 23 } 24 25 26 //二、懒标记下传 27 void down(int k){ 28 xds[2*k].w+=xds[k].f*(xds[2*k].r-xds[2*k].l+1); 29 xds[2*k+1].w+=xds[k].f*(xds[2*k+1].r-xds[2*k+1].l+1); 30 xds[2*k].f+=xds[k].f; 31 xds[2*k+1].f+=xds[k].f; 32 xds[k].f=0;//易漏 33 } 34 35 //三、区间修改 36 void add_(int x,int y,int k,int a){ 37 if(xds[a].l>=x&&xds[a].r<=y){ 38 xds[a].w+=(long long)k*(xds[a].r-xds[a].l+1); 39 xds[a].f+=k; //易漏 ,记得做懒标记 40 return; 41 } 42 if(xds[a].f) down(a);//!!! 43 int m=(xds[a].l+xds[a].r)/2; 44 if(x<=m) add_(x,y,k,a*2); 45 if(y>m) add_(x,y,k,a*2+1); 46 xds[a].w=xds[a*2].w+xds[a*2+1].w; 47 } 48 49 long long ask_(int x,int y,int k) //注意数据范围内,开int只能得70分 50 { 51 if (xds[k].l>=x&&xds[k].r<=y) 52 return xds[k].w; 53 54 if(xds[k].f) down(k); 55 56 int m=(xds[k].l+xds[k].r)/2; 57 long long ans=0; 58 if(x<=m) ans+=ask_(x,y,k*2); 59 if(y>m) ans+=ask_(x,y,k*2+1); 60 return ans; 61 } 62 63 64 int main(){ 65 cin>>n>>m; 66 67 for(int i=1;i<=n;i++) cin>>a[i]; 68 buid(1,n,1); 69 70 for(int i=1;i<=m;i++){ 71 int a,x,y,k; 72 cin>>a; 73 if(a==1) cin>>x>>y>>k,add_(x,y,k,1); 74 if(a==2) cin>>x>>y,cout<<ask_(x,y,1)<<endl; 75 } 76 return 0; 77 }
标签:洛谷,int,线段,long,buid,add,xds,P3372,void 来源: https://www.cnblogs.com/nvwang123/p/10466599.html