题目链接:http://poj.org/problem?id=3468
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.
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<map> 7 #include<set> 8 #include<vector> 9 using namespace std; 10 #define ll long long 11 const int inf=99999999; 12 const int mod=1e9+7; 13 const int maxn=100000+10; 14 typedef struct 15 { 16 int left; 17 int right; 18 ll int weight; 19 ll int lan; 20 } St; 21 St tree[maxn<<2]; 22 int n,m; 23 int a,b; 24 ll int ans; 25 ll int num; 26 inline void build_tree(int k,int left,int right)//建树 27 { 28 tree[k].left=left; 29 tree[k].right=right; 30 if(left==right) 31 { 32 cin>>tree[k].weight; 33 return ; 34 } 35 int mid=(left+right)>>1; 36 build_tree(k<<1,left,mid);//左子树 37 build_tree(k<<1|1,mid+1,right);//右子树 38 tree[k].weight=tree[k<<1].weight+tree[k<<1|1].weight;//状态合并,该节点权重等于左子树加右子树权重 39 } 40 inline void lan_down(int k)//树懒标记下传 41 { 42 tree[k<<1].lan+=tree[k].lan; 43 tree[k<<1|1].lan+=tree[k].lan; 44 tree[k<<1].weight+=tree[k].lan*(tree[k<<1].right-tree[k<<1].left+1); 45 tree[k<<1|1].weight+=tree[k].lan*(tree[k<<1|1].right-tree[k<<1|1].left+1); 46 tree[k].lan=0; 47 } 48 inline void ask_point(int k)//单点查询 49 { 50 if(tree[k].left==tree[k].right) 51 { 52 ans=tree[k].weight; 53 return ; 54 } 55 if(tree[k].lan) 56 lan_down(k); 57 int mid=(tree[k].left+tree[k].right)>>1; 58 if(a<=mid)//a表示单点询问位置 59 ask_point(k<<1);//目标位置靠左,递归左孩子 60 else 61 ask_point(k<<1|1);//目标位置靠右,递归右孩子 62 } 63 inline void add_point(int k)//单点修改 64 { 65 if(tree[k].left==tree[k].right) 66 { 67 tree[k].weight+=num;//单点增加num 68 return ; 69 } 70 if(tree[k].lan)//树懒标记下传 71 lan_down(k); 72 int mid=(tree[k].left+tree[k].right)>>1; 73 if(a<=mid) 74 add_point(k<<1); 75 else 76 add_point(k<<1|1); 77 tree[k].weight=tree[k<<1].weight+tree[k<<1|1].weight;//状态合并 78 } 79 inline void ask_qujian(int k)//区间查询 80 { 81 if(tree[k].left>=a&&tree[k].right<=b)//包含了left,right当前区间,全加上 82 { 83 ans+=tree[k].weight; 84 return ; 85 } 86 if(tree[k].lan)//树懒标记下传 87 lan_down(k); 88 int mid=(tree[k].left+tree[k].right)>>1; 89 if(a<=mid)//递归查询左子区间 90 ask_qujian(k<<1); 91 if(b>mid)//递归查询右子区间 92 ask_qujian(k<<1|1); 93 } 94 inline void add_qujian(int k)//区间修改 95 { 96 if(tree[k].left>=a&&tree[k].right<=b) 97 { 98 tree[k].weight+=num*(tree[k].right-tree[k].left+1); 99 tree[k].lan+=num; 100 return ; 101 } 102 if(tree[k].lan) 103 lan_down(k); 104 int mid=(tree[k].left+tree[k].right)>>1; 105 if(a<=mid) 106 add_qujian(k<<1); 107 if(b>mid) 108 add_qujian(k<<1|1); 109 tree[k].weight=tree[k<<1].weight+tree[k<<1|1].weight;//状态合并 110 } 111 int main() 112 { 113 ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 114 cin>>n>>m; //n个节点,m个操作 115 build_tree(1,1,n);//建树 116 char op; 117 for(int i=0;i<m;i++) 118 { 119 cin>>op>>a>>b; 120 if(op=='Q') 121 { 122 ans=0; 123 ask_qujian(1);//区间查询 124 cout<<ans<<endl; 125 } 126 else if(op=='C') 127 { 128 cin>>num; 129 add_qujian(1);//区间修改 130 } 131 } 132 return 0; 133 }
来源:https://www.cnblogs.com/xwl3109377858/p/10914202.html