NEFU OJ 1266-快乐的雨季-线段树【题解】
题目链接:problem-1266 快乐的雨季
简单说明:
模板题——线段树的区间更新(更新,不是替换)、区间查询。没有什么难以理解的。值得注意的是,数据规模最大的情况下每个点会达到1e9这样子,那么区间和不用long long会溢出。还有多组输入,数组要清空。
my code:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <string> 5 #include <cstdio> 6 #define lson l,mid,k<<1 7 #define rson mid+1,r,k<<1|1 8 #define mset(a,val) memset(a,val,sizeof(a)) 9 using namespace std; 10 typedef long long ll; 11 const int M=1e5+5; 12 13 ll tr[M<<2],lazy[M<<2]; 14 int n,m; 15 16 void pup(int k) 17 { 18 tr[k]=tr[k<<1]+tr[k<<1|1]; 19 } 20 21 void pdown(int len,int k) 22 { 23 24 lazy[k<<1]+=lazy[k]; 25 lazy[k<<1|1]+=lazy[k]; 26 tr[k<<1]+=lazy[k]*(len-(len>>1)); 27 tr[k<<1|1]+=lazy[k]*(len>>1); 28 lazy[k]=0; 29 30 } 31 32 void build(int l,int r,int k) 33 { 34 if(l==r) 35 { 36 tr[k]=lazy[k]=0; 37 return ; 38 } 39 int mid=(l+r)>>1; 40 build(lson); 41 build(rson); 42 pup(k); 43 } 44 45 void range_add(int L,int R,int addv,int l,int r,int k) 46 { 47 if(L<=l&&r<=R) 48 { 49 lazy[k]+=(ll)addv; 50 tr[k]+=(ll)addv*(r-l+1); 51 return ; 52 } 53 if(lazy[k]) 54 pdown(r-l+1,k); 55 int mid=(l+r)>>1; 56 if(L<=mid) 57 range_add(L,R,addv,lson); 58 if(mid<R) 59 range_add(L,R,addv,rson); 60 pup(k); 61 } 62 63 ll range_ask(int L,int R,int l,int r,int k) 64 { 65 if(L<=l&&r<=R) 66 return tr[k]; 67 if(lazy[k]) 68 pdown(r-l+1,k); 69 ll res=0; 70 int mid=(l+r)>>1; 71 if(L<=mid) 72 res+=range_ask(L,R,lson); 73 if(mid<R) 74 res+=range_ask(L,R,rson); 75 return res; 76 } 77 78 int main() 79 { 80 while(~scanf("%d%d",&n,&m)) 81 { 82 mset(tr,0); 83 mset(lazy,0); 84 build(1,n,1); 85 int x,y,val; 86 while(m--) 87 { 88 scanf("%d%d%d",&x,&y,&val); 89 range_add(x,y,val,1,n,1); 90 printf("%lld\n",range_ask(x,y,1,n,1)); 91 } 92 } 93 return 0; 94 }