A Simple Problem with Integers(线段树,区间更新)
Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 83822 | Accepted: 25942 | |
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
Source
题解:线段树区间更新模版,由于mid比较那块出问题了,错了好半天。。。还有就是注意左边的要是x-(x>>1),因为左边可能多一
代码:
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; #define mem(x,y) memset(x,y,sizeof(x)) #define SI(x) scanf("%d",&x) #define SL(x) scanf("%lld",&x) #define PI(x) printf("%d",x) #define P_ printf(" ") #define PL(x) printf("%lld",x) typedef long long LL; const int INF=0x3f3f3f3f; #define ll root<<1 #define rr root<<1|1 #define lson ll,l,mid #define rson rr,mid+1,r #define S(x) tree[x].sum #define L(x) tree[x].lazy const int MAXN=100010; LL ans=0; struct Node{ LL lazy,sum; }; Node tree[MAXN<<2]; void pushup(int root){ S(root)=S(ll)+S(rr); } void pushdown(int root,int x){ if(L(root)){ L(ll)+=L(root); L(rr)+=L(root); S(ll)+=L(root)*(x-(x>>1));//注意 S(rr)+=L(root)*(x>>1); L(root)=0; } } void build(int root,int l,int r){ int mid=(l+r)>>1; L(root)=0; if(l==r){ SL(S(root)); //printf("%d %d %lld\n",l,r,S(root)); return; } build(lson); build(rson); pushup(root); } void update(int root,int l,int r,int A,int B,int v){ int mid=(l+r)>>1; if(l>=A&&r<=B){ L(root)+=v;//注意是+= S(root)+=v*(r-l+1); return; } pushdown(root,r-l+1); if(mid>=A)update(lson,A,B,v);//注意 if(mid<B)update(rson,A,B,v);//注意 pushup(root); } void query(int root,int l,int r,int A,int B){ int mid=(l+r)>>1; //printf("%d %d %lld\n",l,r,S(root)); // PI(A);P_;PI(B); if(l>=A&&r<=B){ ans+=S(root); //printf("%d %d %lld\n",l,r,S(root)); return; } pushdown(root,r-l+1); if(mid>=A)query(lson,A,B);// if(mid<B)query(rson,A,B);// } int main(){ int N,Q; char s[2]; int A,B,v; while(~scanf("%d%d",&N,&Q)){ build(1,1,N); while(Q--){ scanf("%s",s); if(s[0]=='Q'){ scanf("%d%d",&A,&B); ans=0; query(1,1,N,A,B); printf("%lld\n",ans); } else{ scanf("%d%d%d",&A,&B,&v); update(1,1,N,A,B,v); } } } return 0; }
extern "C++"{ #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; typedef long long LL; typedef unsigned u; typedef unsigned long long ull; #define mem(x,y) memset(x,y,sizeof(x)) void SI(double &x){scanf("%lf",&x);} void SI(int &x){scanf("%d",&x);} void SI(LL &x){scanf("%lld",&x);} void SI(u &x){scanf("%u",&x);} void SI(ull &x){scanf("%llu",&x);} void SI(char *s){scanf("%s",s);} void PI(int x){printf("%d",x);} void PI(double x){printf("%lf",x);} void PI(LL x){printf("%lld",x);} void PI(u x){printf("%u",x);} void PI(ull x){printf("%llu",x);} void PI(char *s){printf("%s",s);} #define NL puts(""); #define ll root<<1 #define rr root<<1|1 #define lson ll,l,mid #define rson rr,mid+1,r const int INF=0x3f3f3f3f; const int MAXN=100010; LL tree[MAXN << 2]; LL lazy[MAXN << 2]; } void pushup(int root){ tree[root] = tree[ll] + tree[rr]; } void pushdown(int root,int x){ if(lazy[root]){ lazy[ll] += lazy[root]; lazy[rr] += lazy[root]; // tree[ll]=lazy[root]*(mid-l+1); // tree[rr]=lazy[root]*(r-mid); tree[ll] += lazy[root] * (x - (x >> 1)); tree[rr] += lazy[root] * (x >> 1); lazy[root] = 0; } } void build(int root,int l,int r){ int mid = (l + r) >> 1; lazy[root] = 0; if(l == r){ SI(tree[root]); return ; } build(lson); build(rson); pushup(root); } void update(int root,int l,int r,int L,int R,int C){ if(l >= L && r <= R){ tree[root] += (r - l + 1) * C; lazy[root] += C; return ; } int mid = (l + r) >> 1; pushdown(root,r-l+1); if(mid >= L) update(lson,L,R,C); if(mid < R) update(rson,L,R,C); pushup(root); } LL query(int root,int l,int r,int L,int R){ int mid = (l + r) >> 1; if(l >= L && r <= R){ return tree[root]; } pushdown(root,r-l+1); LL ans = 0; if(mid >= L)ans += query(lson,L,R); if(mid < R)ans += query(rson,L,R); return ans; } int main(){ //assert(false); int N,M; while(~scanf("%d%d",&N,&M)){ build(1,1,N); char s[5]; int l,r,c; while(M--){ SI(s); SI(l);SI(r); if(s[0]=='Q'){ PI(query(1,1,N,l,r)),NL } else{ SI(c); update(1,1,N,l,r,c); } } } return 0; }