POJ 3468 A Simple Problem with Integers
Time Limit:5000MS Memory Limit:131072KB 64bit IO Format:%lld & %llu
Description
给出了一个序列,你需要处理如下两种询问。
"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。
"Q a b" 询问[a, b]区间中所有值的和。
Input
第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.
第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。
接下来Q行询问,格式如题目描述。
Output
对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。
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,我做这题的时候正好在学习刘汝佳的大白《训练指南》模板一套就accepted了 2,就算是熟悉一下吧,这种套模板就可以做对的题目,含金量不是太多,重要在于代码要灵活。#include<iostream> #include<cstdio> #include<cstring> using namespace std; const long long maxn = 100005 ; long long y1,y2,v ; long long _min,_max,_sum ; long long maxv[4*maxn]; long long minv[4*maxn]; long long sumv[4*maxn]; long long addv[4*maxn]; long long n,q; void maintain(long long o,long long L,long long R){ long long lc = o*2,rc = o*2+1 ; sumv[o] = minv[o] = maxv[o] = 0 ; if(R>L){ sumv[o] = sumv[lc] + sumv[rc] ; minv[o] = min(minv[lc],minv[rc]); maxv[o] = max(maxv[lc],maxv[rc]); } minv[o]+=addv[o] ; maxv[o]+=addv[o] ; sumv[o]+=addv[o]*(R-L+1) ; } void update(long long o,long long L,long long R){ long long lc = o*2 ; long long rc = o*2+1 ; if(y1<=L&&y2>=R){ addv[o]+=v ; }else{ long long M = L+(R-L)/2 ; if(y1<=M)update(lc,L,M); if(y2>M)update(rc,M+1,R); } maintain(o,L,R) ; } void query(long long o,long long L,long long R,long long add){ if(y1<=L&&y2>=R){ _sum += sumv[o] + add*(R-L+1) ; _min = min(_min,minv[o]+add) ; _max = max(_max,maxv[o]+add) ; }else{ long long M = L+(R-L)/2 ; if(y1<=M)query(o*2,L,M,add+addv[o]) ; if(y2>M)query(o*2+1,M+1,R,add+addv[o]) ; } } void init() { memset(maxv,-1,sizeof(maxv)) ; memset(minv,0,sizeof(minv)) ; memset(sumv,0,sizeof(sumv)) ; memset(addv,0,sizeof(addv)) ; _sum = 0 ; _max = -1 ; _min = 0x3f3f3f3f ; } int main(){ while(~scanf("%I64d%I64d",&n,&q)){ init() ; for(long long i=0;i<n;i++){ y1=y2=i+1 ; scanf("%I64d",&v); update(1,1,n) ; } char op[2] ; for(long long i=0;i<q;i++){ scanf("%s",op); if(op[0]=='Q'){ scanf("%I64d%I64d",&y1,&y2); query(1,1,n,0) ; printf("%I64d\n",_sum); _sum = 0; }else{ scanf("%I64d%I64d%I64d",&y1,&y2,&v); update(1,1,n) ; } } } return 0; }