poj3468(一维)(区间查询,区间修改)

A Simple Problem with Integers

You have N integers, A1A2, ... , 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 A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+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

The sums may exceed the range of 32-bit integers。
 
还是简单的线段树。
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<cstring>
 6 const int MAXN=100007;
 7 char s[20],c;
 8 long long tree[MAXN*4]={0},add[MAXN*4]={0};
 9 int t,num,x,n,y,m,z,a[MAXN]={0};
10 using namespace std;
11 void build(int l,int r,int p){
12     if (l==r) tree[p]=a[l];
13     else {
14         int mid=(l+r)>>1;
15         build(l,mid,p*2);
16         build(mid+1,r,p*2+1);
17         tree[p]=tree[p*2]+tree[p*2+1];
18     } 
19 }
20 long long query(int l,int r,int p,int x,int y){
21     if (l==x&&r==y) return tree[p]+add[p]*(r-l+1);
22     else {
23         add[p*2+1]+=add[p];
24         add[p*2]+=add[p];
25         tree[p]+=add[p]*(r-l+1);
26         add[p]=0;
27         int mid=(l+r)>>1;
28         if (y<=mid) return query(l,mid,p*2,x,y);    
29         else if(x>=mid+1) return query(mid+1,r,p*2+1,x,y); 
30              else return query(l,mid,p*2,x,mid)+query(mid+1,r,p*2+1,mid+1,y);
31     }
32 }
33 void change(int l,int r,int p,int x,int y,int zhi)
34 {
35     if (l==x&&r==y) add[p]+=zhi;
36     else
37     {
38         tree[p]+=zhi*(y-x+1);
39         int mid=(l+r)>>1;
40         if (y<=mid) change(l,mid,p*2,x,y,zhi);
41         else if (x>mid) change(mid+1,r,p*2+1,x,y,zhi);
42         else
43         {
44             change(l,mid,p*2,x,mid,zhi);
45             change(mid+1,r,p*2+1,mid+1,y,zhi);
46         }
47     }
48 }
49 int main(){
50     while (~scanf("%d%d",&n,&m)){
51         for (int i=1;i<=n;i++)
52             scanf("%d",&a[i]);        
53         build(1,n,1);
54         for (int i=1;i<=m;i++){
55             scanf("%s%d%d",&s,&x,&y);
56             if (s[0]=='Q') printf("%lld\n",query(1,n,1,x,y));
57             else {
58                 scanf("%d",&z);
59                 change(1,n,1,x,y,z);
60             }
61         }
62     }
63 }

 

 线段树虽然简单,但是树状数组就没有这么简单了,差分思想。

转换应该在树状数组blog上已经讲过了,会在blog上持续更新,最新的理解。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 #define N 100007
 7 using namespace std;
 8 
 9 int n,m;
10 long long c[N],d[N];
11 char ch[3];
12 
13 int lowbit(int x)
14 {
15     return x&(-x);
16 }
17 void change(int x,int y,int z)
18 {
19     for (int i=x;i<=n;i+=lowbit(i))
20         c[i]+=z;
21     for (int i=y+1;i<=n;i+=lowbit(i))
22         c[i]-=z;
23         
24     for (int i=x;i<=n;i+=lowbit(i))
25         d[i]+=(long long)z*x;
26     for (int i=y+1;i<=n;i+=lowbit(i))
27         d[i]-=(long long)z*(y+1);            
28 }
29 long long query(int x)
30 {
31     long long res=0,ans=0;
32     for (int i=x;i>=1;i-=lowbit(i))
33         res+=c[i];
34     ans+=res*(x+1);
35     res=0;
36     for (int i=x;i>=1;i-=lowbit(i))
37         res+=d[i];
38     ans-=res;
39     return ans;        
40 }
41 int main()
42 {
43     scanf("%d%d",&n,&m);
44     int last=0,x,y,z;
45     for (int i=1;i<=n;i++)
46     {
47         scanf("%d",&x);
48         y=x-last;
49         change(i,n,y);
50         last=x;
51     }
52     for (int i=1;i<=m;i++)
53     {
54         scanf("%s",ch);
55         if (ch[0]=='Q')
56         {
57             scanf("%d%d",&x,&y);
58             printf("%lld\n",query(y)-query(x-1));
59         }
60         else
61         {
62             scanf("%d%d%d",&x,&y,&z);
63             change(x,y,z);
64         }
65     }
66 }

 

posted @ 2017-09-17 13:34  Kaiser-  阅读(144)  评论(0编辑  收藏  举报