标签:
Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 94899 | Accepted: 29568 | |
Case Time Limit: 2000MS |
Description
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
Output
You need to answer all Q commands in order. One answer in a line.
Sample Input
10 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4
Sample Output
4 55 9 15
Hint
Source
看了某个大神写的线段树,感觉要改习惯了555 因为这个大神的线段树方式比以前我习惯写的内个要方便
这里说一下延迟标记或者说懒惰标记的意思
举个栗子,如果让[1,5]里面所有数加1,那么当二分到的这个区间如果正好包含在[1,5]里面,那么为了节约查询的时间,将add+=1 sum+=1*len,后面的子节点可以不考虑。如果后来查询或者更新这个区间的子节点的话将原来这个标记下传,因为原来由于直接包含了这个区间,为了节约时间就没去更新他的子节点,现在需要更新他的子节点了,所以要标记下传 (⊙o⊙)如果还是不懂,那就给你原本zhx大神给我的建议:自己手跑一遍
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <cstdlib> 5 #include <queue> 6 #include <vector> 7 #include <stack> 8 #include <iostream> 9 #include "algorithm" 10 using namespace std; 11 typedef long long LL; 12 13 #define lson rt<<1,l,m 14 #define rson rt<<1|1,m+1,r 15 16 const int MAX=100005; 17 18 int n,m; 19 LL sum[MAX<<2]; 20 LL add[MAX<<2]; 21 22 void PushUp(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];} 23 24 void PushDown(int rt,int m){ 25 if (add[rt]) 26 {add[rt<<1]+=add[rt]; 27 add[rt<<1|1]+=add[rt]; 28 sum[rt<<1]+=add[rt]*(LL)(m-(m>>1));//很重要!!一开始被坑了!!原因可以自己举个栗子算一下 29 sum[rt<<1|1]+=add[rt]*(LL)(m>>1); 30 add[rt]=0; 31 } 32 } 33 34 void build(int rt,int l,int r){ 35 add[rt]=0; 36 if (l==r) 37 {scanf("%lld",&sum[rt]); 38 return; 39 } 40 int m=(l+r)>>1; 41 build(lson); 42 build(rson); 43 PushUp(rt); 44 } 45 46 void update(int rt,int l,int r,int x,int y,int z){ 47 if (x<=l && r<=y) 48 {add[rt]+=(LL)z; 49 sum[rt]+=(LL)z*(LL)(r-l+1); 50 return; 51 } 52 PushDown(rt,r-l+1); 53 int m=(l+r)>>1; 54 if (x<=m) 55 update(lson,x,y,z); 56 if (y>m) 57 update(rson,x,y,z); 58 PushUp(rt); 59 } 60 61 LL search(int rt,int l,int r,int x,int y){ 62 if (x<=l && r<=y) 63 return sum[rt]; 64 PushDown(rt,r-l+1); 65 int m=(l+r)>>1; 66 LL ans(0); 67 if (x<=m) 68 ans+=search(lson,x,y); 69 if (y>m) 70 ans+=search(rson,x,y); 71 return ans; 72 } 73 int main(){ 74 freopen ("intergers.in","r",stdin); 75 freopen ("intergers.out","w",stdout); 76 int i,j; 77 int x,y,z; 78 char c; 79 scanf("%d%d",&n,&m); 80 build(1,1,n); 81 for (i=1;i<=m;i++) 82 {c=getchar(); 83 while (!(c==‘Q‘ || c==‘C‘)) c=getchar(); 84 if (c==‘Q‘) 85 {scanf("%d%d",&x,&y); 86 printf("%lld\n",search(1,1,n,x,y)); 87 } 88 else 89 {scanf("%d%d%d",&x,&y,&z); 90 update(1,1,n,x,y,z); 91 } 92 } 93 return 0; 94 }
POJ-3468 A Simple Problem with Integers(线段树)
标签:
原文地址:http://www.cnblogs.com/Michaelzzn/p/5745139.html