A Simple Problem with Integers
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
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
报告
题目大意: 一串数,“C a b c" 表示在区间[a,b]中每个数 + c
"Q a b"表示查询区间[a,b] 的和
线段树: 学习了线段树后的第一道题。这道题包含了线段树的Pushdown,Pushup,Query,Build,Update几个函数,很好地让初学者了解了线段树的用法和精髓--延迟更新,即每次更新时只是做一个标记,当要查找时才继续向下更新。还要注意的是,有些题不需要向下回溯(pushup),也不需要延迟更新(pushdown),甚至连更新都不用。但是需要根据题意改变要查找的内容和更新的内容,有的需要找最大值,有的需要找和,等等,需要随机应变。线段树能解决的问题,树状数组不一定能解决,但是树状数组能解决的,线段树一定能解决。
思路: 便不多说。上代码。
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 #include<cstdio> 5 #define L(u) (u<<1) 6 #define R(u) (u<<1|1)//没有分号 7 using namespace std; 8 int n,q; 9 long long c; 10 long long a[100005]; 11 struct node{ 12 int l,r; 13 long long add,sum; 14 }; 15 char s[2]; 16 node pp[400005];/**数据范围**/ 17 void pushup(int u) 18 { 19 pp[u].sum=pp[L(u)].sum+pp[R(u)].sum; 20 return ; 21 } 22 void pushdown(int u) 23 { 24 pp[L(u)].add+=pp[u].add; 25 pp[L(u)].sum+=(pp[L(u)].r-pp[L(u)].l+1)*pp[u].add; 26 pp[R(u)].add+=pp[u].add; 27 pp[R(u)].sum+=(pp[R(u)].r-pp[R(u)].l+1)*pp[u].add; 28 pp[u].add=0;/*!!!*/ 29 } 30 void update(int u,int left,int right,long long t) 31 { 32 if (left<=pp[u].l&&pp[u].r<=right) 33 { 34 pp[u].add+=t; 35 pp[u].sum+=(pp[u].r-pp[u].l+1)*t; 36 return ; 37 } 38 pp[u].sum+=(right-left+1)*t; 39 if (pp[u].add) pushdown(u); 40 int mid=(pp[u].l+pp[u].r)>>1; 41 if (right<=mid) update(L(u),left,right,t); 42 else /***/if (left>mid) update(R(u),left,right,t); 43 else 44 { 45 update(L(u),left,mid,t); 46 update(R(u),mid+1,right,t); 47 } 48 //pushup(u); 49 } 50 51 void build(int u,int left,int right) 52 { 53 pp[u].l=left; 54 pp[u].r=right; 55 pp[u].add=0; 56 if (pp[u].l==pp[u].r) 57 { 58 pp[u].sum=a[left];//***** 59 return ; 60 } 61 int mid=(pp[u].l+pp[u].r)>>1; 62 build(L(u),left,mid); 63 build(R(u),mid+1,right); 64 pushup(u); 65 } 66 long long query(int u,int left,int right) 67 { 68 if (left==pp[u].l&&pp[u].r==right) 69 return pp[u].sum; 70 if (pp[u].add) pushdown(u); 71 int mid=(pp[u].l+pp[u].r)>>1; 72 if (right<=mid) return query(L(u),left,right); 73 if (left>mid) return query(R(u),left,right); 74 else 75 return (query(L(u),left,mid)+query(R(u),mid+1,right)); 76 } 77 int main() 78 { 79 //freopen("tree.in","r",stdin); 80 cin>>n>>q; 81 for (int i=1;i<=n;i++) 82 scanf("%lld",&a[i]);//long long 读数 83 build(1,1,n); 84 for (int i=1;i<=q;i++) 85 { 86 scanf("%s",s); 87 if (s[0]=='Q') 88 { 89 int k,b; 90 scanf("%d%d",&k,&b); 91 cout<<query(1,k,b)<<endl; 92 } 93 else 94 { 95 int k,b; 96 cin>>k>>b>>c; 97 update(1,k,b,c); 98 } 99 } 100 101 return 0; 102 }
注意事项:1、数据范围:线段树一般定义4*n
2、#difine 的使用 function() ( ** ) 注意括号没有分号;
3、runtime error :运行错误 long long a[i], %lld(linux) %I64d (windows)
4、模板答题
顺便抱怨一下,poj的评测系统太慢了,waiting了好久.......