题目描述
给定一个长度为n(n<=100000),初始值都为0的序列,x(x<=10000)次的修改某些位置上的数字,每次加上一个数,然后提出y (y<=10000)个问题,求每段区间的和。时间限制1秒。
输入输出格式
输入格式:
第一行1个数,表示序列的长度n
第二行1个数,表示操作的次数w
后面依次是w行,分别表示加入和询问操作
其中,加入用x表示,询问用y表示
x的格式为"x a b" 表示在序列a的位置加上b
y的格式为"y a b" 表示询问a到b区间的加和
输出格式:
每行一个数,分别是每次询问的结果
输入输出样例
输入样例#1: 复制
5 4 x 3 8 y 1 3 x 4 9 y 3 4
输出样例#1: 复制
8 17
线段数做法:
// luogu-judger-enable-o2 #include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #define maxn 100007 using namespace std; int n,m,x,y,z; char jjj[4]; long long Sum[maxn<<2],Add[maxn<<2]; int A[maxn]; void PushUp(int rt){Sum[rt]=Sum[rt*2]+Sum[rt*2+1];} void Build(int l,int r,int rt){ if(l==r) { Sum[rt]=A[l]; return; } int m=(l+r)>>1; Build(l,m,rt<<1); Build(m+1,r,rt<<1|1); PushUp(rt); } void PushDown(int rt,int ln,int rn){ if(Add[rt]){ Add[rt<<1]+=Add[rt]; Add[rt<<1|1]+=Add[rt]; Sum[rt<<1]+=Add[rt]*ln; Sum[rt<<1|1]+=Add[rt]*rn; Add[rt]=0; } } long long Query(int L,int R,int l,int r,int rt){ if(L <= l && r <= R) return Sum[rt]; int m=(l+r)>>1; PushDown(rt,m-l+1,r-m); long long ANS=0; if(L <= m) ANS+=Query(L,R,l,m,rt<<1); if(R > m) ANS+=Query(L,R,m+1,r,rt<<1|1); return ANS; } void Update(int L,int R,int C,int l,int r,int rt){ if(L <= l && r <= R){ Sum[rt]+=C*(r-l+1); Add[rt]+=C; return ; } int m=(l+r)>>1; PushDown(rt,m-l+1,r-m); if(L <= m) Update(L,R,C,l,m,rt<<1); if(R > m) Update(L,R,C,m+1,r,rt<<1|1); PushUp(rt); } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++) A[i]=0; Build(1,n,1); while(m--) { scanf("%s",jjj); if(jjj[0]=='x') { scanf("%d%d",&x,&z); Update(x,x,z,1,n,1); } else { scanf("%d%d",&x,&y); printf("%lld ",Query(x,y,1,n,1)); } } } return 0; }
树状数组解法如下:
’
#include<iostream> using namespace std; const int MAXN=100000+2; int a[MAXN]; int n,w; int lowbit(int x){ return x&(-x); } void add(int p,int x){ while(p<=n){ a[p]+=x; p+=lowbit(p); } } int ask(int p){ int ans=0; while(p>0){ ans+=a[p]; p-=lowbit(p); } return ans; } int main(){ cin>>n>>w; for(int i=1;i<=w;i++){ char q; int y,z; cin>>q>>y>>z; if(q=='x') add(y,z); else cout<<ask(z)-ask(y-1)<<endl; } return 0; }