A Simple Problem with Integers
Time Limit: 5000MS | Memory Limit: 131072K |
---|---|
Total Submissions: 211861 | Accepted: 64751 |
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
BIT
#include <stdio.h>
#include <cctype>
#define ll long long
#define rep(i,a,n) for(int i=a;i<n;i++)
template <typename T>
inline void in(T &x){
x=0;
int f=0;char ch=getchar();
for(;!isdigit(ch);ch=getchar()){f|=ch=='-';}
for(;isdigit(ch);ch=getchar()){x = (x<<3) + (x<<1) + (ch^48);}
if(f)x=-x;
}
inline void out(ll x){
if(x<0)putchar('-'),x=-x;
if(x>9)out(x/10);
putchar(x%10+'0');
}
int n,m,l,r,k;
char p;
const int MAXN = 100001;
int a[MAXN]={0};
ll sum1[MAXN]={0};
ll sum2[MAXN]={0};
void update(int i,int x){
int d=i;
while(i<=n){
sum1[i]+=x;
sum2[i]+=1LL*(d-1)*x;
i+=i&-i;
}
}
ll sum(int i){
int d=i;
ll res=0;
while(i>0){
res+=sum1[i]*d-sum2[i];
i-=i&-i;
}
return res;
}
int main(){
in(n);in(m);
rep(i,1,n+1){
in(a[i]);
update(i,a[i]-a[i-1]);
}
while(m--){
p=getchar();
if(p=='Q'){
in(l);in(r);
out(sum(r)-sum(l-1));
putchar('\n');
}
else{
in(l);in(r);in(k);
update(l,k);update(r+1,-k);
}
}
return 0;
}
线段树Segment Tree
#include <stdio.h>
#include <cctype>
#include <math.h>
#define rep(i,a,n) for(int i=a;i<n;i++)
#define ll long long
#define ls(i) (i<<1)
#define rs(i) (i<<1|1)
template <typename T>
inline void in(T &x){
x=0;
int f=0;char ch=getchar();
for(;!isdigit(ch);ch=getchar()){f|=ch=='-';}
for(;isdigit(ch);ch=getchar()){x = (x<<3) + (x<<1) + (ch^48);}
if(f)x=-x;
}
template <typename T>
inline void out(T x){
if(x<0)putchar('-'),x=-x;
if(x>9)out(x/10);
putchar(x%10+'0');
}
int n,m,l,r,_k;
char p;
const int M = 100001;
int a[M]={0};
struct node{
ll lz;
int l;
int r;
ll sum;
node():lz(0),sum(0){}
}tr[(2<<17)-1];
inline void build(int i,int L,int R){
tr[i].l=L;tr[i].r=R;
if(L==R){
tr[i].sum=a[L-1];
return;
}
int mid=(L+R)>>1;
build(ls(i),L,mid);
build(rs(i),mid+1,R);
tr[i].sum=tr[ls(i)].sum+tr[rs(i)].sum;
}
inline void pushdown(int i){
if(tr[i].lz){
tr[ls(i)].lz+=tr[i].lz;
tr[rs(i)].lz+=tr[i].lz;
tr[ls(i)].sum+=tr[i].lz*(tr[ls(i)].r-tr[ls(i)].l+1);
tr[rs(i)].sum+=tr[i].lz*(tr[rs(i)].r-tr[rs(i)].l+1);
tr[i].lz=0;
}
}
inline void update(int i,int L,int R,int k){
if(tr[i].l>=L&&tr[i].r<=R){
tr[i].sum+=1LL*k*(tr[i].r-tr[i].l+1);
tr[i].lz+=k;
return;
}
pushdown(i);
if(tr[ls(i)].r>=L)update(ls(i),L,R,k);
if(tr[rs(i)].l<=R)update(rs(i),L,R,k);
tr[i].sum=tr[ls(i)].sum+tr[rs(i)].sum;
}
inline ll query(int i,int L,int R){
if(tr[i].l>=L&&tr[i].r<=R)return tr[i].sum;
if(tr[i].l>R||tr[i].r<L)return 0;
pushdown(i);
ll res=0;
if(tr[ls(i)].r>=L)res+=query(ls(i),L,R);
if(tr[rs(i)].l<=R)res+=query(rs(i),L,R);
return res;
}
int main(){
in(n);in(m);
rep(i,0,n)in(a[i]);
build(1,1,n);
while(m--){
p=getchar();in(l);in(r);
if(p=='Q'){
out(query(1,l,r));
putchar('\n');
}
else{
in(_k);
update(1,l,r,_k);
}
}
return 0;
}