时间限制:1 s 内存限制:160 MB
【问题描述】
假设有一列数 {Ai }(1 ≤ i ≤ n) ,支持如下两种操作:
(1)将 A k 的值加 D 。( k, D 是输入的数)
(2) 输出 A s +A s+1 +…+A t 。( s, t 都是输入的数, S ≤ T )
根据操作要求进行正确操作并输出结果。
【输入格式】
输入文件第一行一个整数 n(0<=n<=100000) , 第二行为 n 个整数,表示 {A i } 的初始值。
第三行为一个整数 m(0<=m<=150000) ,表示操作数。 下接 m 行,每行描述一个操作,有如下两种情况:
ADD k d ( 表示将 A k 加 d , 1<=k<=n , d 为整数 )
SUM s t (表示输出 A s +…+A t )
【输出格式】
对于每一个 SUM 提问,输出结果
【输入输出样例】
输入:
4
1 4 2 3
3
SUM 1 3
ADD 2 50
SUM 2 3
输出:
7
56
线段树模版题
区间查询,单点修改
#include <iostream> #include <cstdio> #include <string> #define Max 100000 using namespace std; int n,m,ans; struct node { int l,r,dis; int mid; void get_mid(){mid=(l+r)>>1;} }tree[Max*4+1]; void up(int k) { tree[k].dis=tree[k<<1].dis+tree[k<<1|1].dis; } void build(int l,int r,int k) { tree[k].l=l; tree[k].r=r; tree[k].get_mid(); if(l==r) { scanf("%d",&tree[k].dis); return; } int mid=(l+r)>>1; build(l,mid,k<<1); build(mid+1,r,k<<1|1); up(k); } char cz[11]; void add(int to,int v,int k) { if(tree[k].l==tree[k].r) { tree[k].dis+=v; return; } int mid=tree[k].mid; if(mid>=to) add(to,v,k<<1); else add(to,v,k<<1|1); up(k); } int sum(int u,int v,int k) { if(tree[k].l==u&&tree[k].r==v) { return tree[k].dis; } if(v<=tree[k].mid) return sum(u,v,k<<1); else if(u>tree[k].mid) return sum(u,v,k<<1|1); else { return sum(u,tree[k].mid,k<<1)+sum(tree[k].mid+1,v,k<<1|1); } } int main() { freopen("shulie.in","r",stdin); freopen("shulie.out","w",stdout); scanf("%d",&n); build(1,n,1); scanf("%d",&m); int u,v; while(m--) { cin>>cz; if(cz[0]=='A') { scanf("%d%d",&u,&v); add(u,v,1); } else if(cz[0]=='S') { scanf("%d%d",&u,&v); printf("%d ",sum(u,v,1)); } } return 0; }