CODEVS 1080线段树练习
2016-11-01 22:31
387 查看
#include<stdio.h> #include<iostream> using namespace std; int n,m,sum[400001],a[100010],x,y,z; int dfs(int o,int l,int r){//以sum数组构建线段树,节点o,这个节点为从l到r的和 int mid=(l+r)/2;//中点 if(l==r) return sum[o]=a[l];//叶节点 该点值即为自己(长度为1) else return sum[o]=dfs(2*o,l,mid)+dfs(2*o+1,mid+1,r);//o点的值为左子树+右子树 } void add(int o,int l,int r){//给 y 位置加上 z,从上向下递归,如果该节点包含y位置,这个节点就要加z int mid=(l+r)/2;//中点 sum[o]+=z; if(l==r) return;//递归到叶节点,返回 if(y<=mid) add(2*o,l,mid);//y在左半段 else add(2*o+1,mid+1,r);//y在右半段 return;//返回 } int ssum(int o,int l,int r){//求[y,z]区间之和 int mid=(l+r)/2,ans=0;//中点 if(y<=l&&r<=z) return sum[o];//当搜索到一个区间[l,r]被[y,z]包含时立刻return if(y<=mid) ans+=ssum(2*o,l,mid);//[y,z]横跨mid时 if(mid+1<=z) ans+=ssum(2*o+1,mid+1,r);//[y,z]横跨mid时 return ans; } int main(){ freopen("1080.in","r",stdin); freopen("1080.out","w",stdout); cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; dfs(1,1,n); cin>>m; for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); if(x==1) add(1,1,n); if(x==2) printf("%d\n",ssum(1,1,n)); } return 0; }
题解:线段树基础入门,详见备注。
相关文章推荐
- CODEVS 1080 线段树练习
- codevs 1080_线段树练习_树状数组
- CodeVS 1080 线段树练习 分块 块状数组
- codevs 1080 线段树练习
- codevs 1080 线段树练习
- 1080 线段树练习 codevs
- codevs 1080 线段树练习
- AC日记——线段树练习5 codevs 4927
- 1080 线段树练习
- codevs1080 线段树练习
- 【codevs 1080】线段树练习 之 花样解法
- codevs 4919 线段树练习4
- 【codevs 1080~1082】线段树练习重做
- codevs 1080 线段树练习
- codevs 1080 线段树练习 CDQ分治
- 【数据结构】树状数组模板--CODE[VS] 1080线段树练习and1081线段树练习2
- CODE[VS] 1080 线段树练习(单值修改、区间求和)
- [Codevs] 1080 线段树练习
- 【codevs 1080~1082】线段树练习重做
- codevs_5037 线段树练习4加强版