POJ3468(线段树区间求和+区间查询)

https://vjudge.net/contest/66989#problem/C

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


 1 //线段树区间和裸题
 2 //#include<bits/stdc++.h>
 3 #include<iostream>
 4 #include<stdio.h>
 5 #include<string.h>
 6 #define lson l,m,rt<<1
 7 #define rson m+1,r,rt<<1|1
 8 using namespace std;
 9 const int maxn=100005;
10 long long sum[maxn<<2],add[maxn<<2];
11 void pushup(int rt)
12 {
13     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
14 }
15 void pushdown(int rt,int ln,int rn)
16 {
17     if(add[rt])
18     {
19         sum[rt<<1]+=add[rt]*ln;
20         sum[rt<<1|1]+=add[rt]*rn;
21         add[rt<<1]+=add[rt];
22         add[rt<<1|1]+=add[rt];
23         add[rt]=0;
24     }
25 }
26 void build(int l,int r,int rt)
27 {
28     if(r==l)
29     {
30         scanf("%lld",&sum[rt]);
31         return;
32     }
33     int m=(l+r)>>1;
34     build(lson);
35     build(rson);
36     pushup(rt);
37 }
38 void update(int L,int R,int c,int l,int r,int rt)
39 {
40    if(L<=l&&R>=r)
41    {
42        sum[rt]+=(long long)c*(r-l+1);
43        add[rt]+=c;
44        return;
45    }
46    int m=(l+r)>>1;
47    pushdown(rt,m-l+1,r-m);
48    if(L<=m)
49     update(L,R,c,lson);
50    if(R>m)
51     update(L,R,c,rson);
52     pushup(rt);
53 }
54 long long query(int L,int R,int l,int r,int rt)
55 {
56     if(L<=l&&R>=r)
57     {
58         return sum[rt];
59     }
60     int m=(r+l)>>1;
61     pushdown(rt,m-l+1,r-m);
62     long long ans=0;
63     if(L<=m)
64         ans+=query(L,R,lson);
65     if(R>m)
66         ans+=query(L,R,rson);
67     return ans;
68 }
69 int main()
70 {
71     ios::sync_with_stdio(false);
72     cin.tie(0);
73     int n,m,x,y,z,q;
74     char h;
75     while(~scanf("%d%d",&n,&q))
76     {
77     memset(sum,0,sizeof sum);
78     memset(add,0,sizeof add);
79     build(1,n,1);
80     for(int i=1;i<=q;i++)
81     {
82         getchar();
83         scanf("%c",&h);
84         if(h=='Q')
85         {
86             scanf("%d%d",&x,&y);
87             cout<<query(x,y,1,n,1)<<endl;
88         }
89         else if(h=='C')
90         {
91             scanf("%d%d%d",&x,&y,&z);
92             update(x,y,z,1,n,1);
93         }
94     }
95     }
96     return 0;
97 }

注意点:

是道裸题了

BUT 在输入数据的时候 ,scanf("%lld",&sum[rt]);一开始把它写成%d了,害我WA了好几发;

sum[rt]+=(long long)c*(r-l+1); 一开始没注意把数据转化为long long(>人<;)。

以后一定要注意呀!

原文地址:https://www.cnblogs.com/zuiaimiusi/p/10752963.html