【poj】A Simple Problem with Integers-(区间加减,查询区间总和)。

A Simple Problem with Integers
Time Limit: 5000MS   Memory Limit: 131072K
Total Submissions: 71967   Accepted: 22196
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

The sums may exceed the range of 32-bit integers.

Source

题目大意:对一段区间的全部数进行加减(区间加减),或者查询区间总和;
  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <string.h>
  4 #include <algorithm>
  5 using namespace std;
  6 typedef long long LL;
  7 typedef struct Line
  8 {
  9     LL Left,Right;
 10     LL Key;/*关键值*/
 11     LL Times;/*计数器*/
 12     LL Count;
 13 }LR;
 14 LR ID[100860];/*每一个节点都需要一个存储*/
 15 LL Key_SUM;
 16 LL UP_Key(LL n)
 17 {
 18     return ID[n*2].Key+ID[n*2+1].Key;
 19 }
 20 LL UP_Count(LL n)
 21 {
 22     return ID[n*2].Count+ID[n*2+1].Count;
 23 }
 24 void Build(LL L,LL R,LL n)    /*输入时建立二叉树根*/
 25 {
 26     LL Mid=(L+R)/2;
 27     ID[n].Left=L;ID[n].Right=R;
 28     ID[n].Key=0;ID[n].Times=0;/*初始化为0*/
 29     if (L==R)/*找到根节点的时候结束*/
 30     {
 31         scanf("%I64d",&ID[n].Key);
 32         ID[n].Count=1;return;
 33     }
 34     Build(L,Mid,2*n);Build(Mid+1,R,2*n+1);
 35     ID[n].Key=UP_Key(n);ID[n].Count=UP_Count(n);
 36 }
 37 
 38 void Search(LL L,LL R,LL Step)/*求区间和*/
 39 {
 40     if(L==ID[Step].Left && R==ID[Step].Right)
 41     {
 42        Key_SUM+=ID[Step].Key+ID[Step].Times*(R-L+1);
 43        return ;
 44     }
 45     if(ID[Step].Times!=0)
 46     {
 47         ID[Step*2].Times+=ID[Step].Times;
 48         ID[Step*2+1].Times+=ID[Step].Times;
 49         ID[Step].Key+=(ID[Step].Right-ID[Step].Left+1)*ID[Step].Times;
 50         ID[Step].Times=0;
 51     }
 52     LL Mid=(ID[Step].Left+ID[Step].Right)/2;
 53     if (Mid>=R)Search(L,R,Step*2);
 54     else if (Mid<L)Search(L,R,Step*2+1);
 55     else
 56     {
 57          Search(L,Mid,Step*2);
 58          Search(Mid+1,R,Step*2+1);
 59     }
 60 }
 61 void UpData(LL L,LL R,LL Step,LL num)/*区域更新*/
 62 {
 63     if(L==ID[Step].Left && R==ID[Step].Right)
 64         {ID[Step].Times+=num;return;}
 65     ID[Step].Key+=num*(R-L+1);
 66     LL Mid=(ID[Step].Left+ID[Step].Right)/2;
 67     if (Mid>=R)     UpData(L,R,Step*2,num);
 68     else if (Mid<L)    UpData(L,R,Step*2+1,num);
 69     else
 70     {
 71         UpData(L,Mid,Step*2,num);
 72         UpData(Mid+1,R,Step*2+1,num);
 73     }
 74 }
 75 
 76 int main()
 77 {
 78     LL N,i,a,b,c,q;
 79     while(scanf("%I64d%I64d",&N,&q)!=EOF)
 80     {
 81         Build(1,N,1);
 82         char Str;
 83         while(q--)
 84         {
 85             scanf(" %c",&Str);
 86             if(Str=='Q')
 87             {
 88                 scanf("%I64d%I64d",&a,&b);
 89                 Key_SUM=0;Search(a,b,1);
 90                 printf("%I64d\n",Key_SUM);
 91             }
 92             else
 93             {
 94                 scanf("%I64d%I64d%I64d",&a,&b,&c);
 95                 UpData(a,b,1,c);
 96             }
 97         }
 98     }
 99     return 0;
100 }
View Code

 更新模板:(2016.4.14)

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 #define MaxN 1008600
 6 using namespace std;
 7 typedef long long LL;
 8 LL Len;
 9 struct Node{LL L,R,Key,Add;}ID[MaxN];/*每一个节点都需要一个存储*/
10 LL Up_Date(LL n){/*向上更新,区间汇总*/
11     return ID[2*n].Key+ID[2*n+1].Key;
12 }
13 void Down_Date(LL n){/*向下更新*/
14     if(ID[n].Add!=0){
15         ID[2*n].Add+=ID[n].Add;
16         ID[2*n+1].Add+=ID[n].Add;
17         ID[n].Key+=(ID[n].R-ID[n].L+1)*ID[n].Add;
18         ID[n].Add=0;
19     }
20 }
21 void Build(LL L,LL R,LL n)/*输入时建立二叉树根,Build(1,N,1)*/
22 {
23     ID[n].L=L;ID[n].R=R;
24     ID[n].Add=0;ID[n].Key=0;
25     if (L==R){/*根据要求赋值*/
26         scanf("%I64d",&ID[n].Key);return;
27     }
28     LL Mid=(L+R)/2;
29     Build(L,Mid,2*n);Build(Mid+1,R,2*n+1);
30     ID[n].Key=Up_Date(n);
31 }
32 
33 void UpDate_L(LL L,LL R,LL n,LL v)/*区间更新,标记区间*/
34 {
35     if(L==ID[n].L && R==ID[n].R){
36         ID[n].Add+=v;return ;
37     }
38     ID[n].Key+=v*(R-L+1);
39     //Down_Date(n);/*可以每次更新,提高效率*/
40     LL Mid=(ID[n].L+ID[n].R)/2;
41     if (Mid>=R) UpDate_L(L,R,n*2,v);
42     else if (Mid<L) UpDate_L(L,R,n*2+1,v);
43     else{
44         UpDate_L(L,Mid,n*2,v);
45         UpDate_L(Mid+1,R,n*2+1,v);
46     }
47 }
48 
49 LL Query(LL L,LL R,LL n)/*询问匹配区间*/
50 {
51     if(L==ID[n].L && R==ID[n].R){
52         return ID[n].Key+ID[n].Add*(R-L+1);
53     }
54     Down_Date(n);
55     LL Mid=(ID[n].L+ID[n].R)/2;
56     if (Mid>=R)return Query(L,R,n*2);
57     else if (Mid<L)return Query(L,R,n*2+1);
58     else{
59         return Query(L,Mid,n*2)+Query(Mid+1,R,n*2+1);
60     }
61 }
62 int main()
63 {
64     char Str;
65     LL T,t=1,N,M,i;
66     LL A,B,C;
67     while(scanf("%I64d%I64d",&N,&M)!=EOF)
68     {
69         Build(1,N,1);Len=N;
70         for(i=0;i<M;i++){
71             scanf(" %c",&Str);
72             switch(Str){
73                 case 'Q':scanf("%I64d%I64d",&A,&B);printf("%I64d\n",Query(A,B,1));break;
74                 case 'C':scanf("%I64d%I64d%I64d",&A,&B,&C);UpDate_L(A,B,1,C);break;
75             }
76         }
77     }
78     return 0;
79 }
View Code

 

posted @ 2015-05-17 17:13  Wurq  阅读(189)  评论(0编辑  收藏  举报