<线段树系列2> codevs 1082 线段树练习2
2017-08-13 18:12
399 查看
还是一道很简单的线段树模板
给你N个数,有两种操作
1:给区间[a,b]的所有数都增加X
2:询问第i个数是什么?
输入描述 Input Description
第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数。如果第一个数是1,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是2,后面跟1个整数i, 表示询问第i个位置的数是多少。
输出描述 Output Description
对于每个询问输出一行一个答案
样例输入 Sample Input
3
1
2
3
2
1 2 3 2
2 3
样例输出 Sample Output
5
数据范围及提示 Data Size & Hint
1<=n<=100000
1<=q<=100000
一句话:单点查询,区间修改
代码:
codevs 1082 线段树练习2
题目描述 Description给你N个数,有两种操作
1:给区间[a,b]的所有数都增加X
2:询问第i个数是什么?
输入描述 Input Description
第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数。如果第一个数是1,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是2,后面跟1个整数i, 表示询问第i个位置的数是多少。
输出描述 Output Description
对于每个询问输出一行一个答案
样例输入 Sample Input
3
1
2
3
2
1 2 3 2
2 3
样例输出 Sample Output
5
数据范围及提示 Data Size & Hint
1<=n<=100000
1<=q<=100000
一句话:单点查询,区间修改
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; const int maxn=1e5+5; int n,q; int a[maxn]; struct hh { int l,r; int summ,add; }tree[maxn<<2]; void Updata(int i,int x) { tree[i].summ+=x*(tree[i].r-tree[i].l+1); } void Spread(int i) { int &xa=tree[i].add; if(xa) { tree[i<<1].add+=xa; tree[i<<1|1].add+=xa; Updata(i<<1,xa); Updata(i<<1|1,xa); xa=0; } } void Add(int l,int r,int x,int i) { int lx=tree[i].l; int rx=tree[i].r; if(lx>=l&&rx<=r) { tree[i].add+=x; Updata(i,x); return; } Spread(i); int mid=(lx+rx)>>1; if(l<=mid) Add(l,r,x,i<<1); if(r>mid) Add(l,r,x,i<<1|1); tree[i].summ=tree[i<<1].summ+tree[i<<1|1].summ; } int Ask(int x,int i) { if(tree[i].l==tree[i].r) return tree[i].summ; Spread(i); int mid=(tree[i].l+tree[i].r)>>1; if(x<=mid) return Ask(x,i<<1); if(x>mid) return Ask(x,i<<1|1); } int Build(int l,int r,int i) { tree[i].l=l; tree[i].r=r; if(l==r) { tree[i].summ=a[l]; return a[l]; } int mid=(r+l)>>1; return tree[i].summ=Build(l,mid,i<<1)+Build(mid+1,r,i<<1|1); } int main() { scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]); Build(1,n,1); scanf("%d",&q); for(int i=1;i<=q;++i) { int ques; scanf("%d",&ques); if(ques==1) { int a,b,x; scanf("%d%d%d",&a,&b,&x); Add(a,b,x,1); } else { int love; scanf("%d",&love); printf("%d\n",Ask(love,1)); } } return 0; }
相关文章推荐
- <线段树系列3> codevs 1082 线段树练习3
- <线段树系列1> codevs 1080 线段树练习
- <线段树系列4> codevs 4927 线段树练习5
- codevs 1080~1082 线段树练习系列(模板)
- 【codevs1082】线段树练习3 线段树
- 【codevs 1080~1082】线段树练习重做
- 【CODE[VS]】1082 线段树练习 3 树状数组
- codevs 1082 线段树练习 3
- COdeVS——T 1082 线段树练习 3 (分块练习)
- 【codevs1082】线段树练习 3
- 【codevs 1080~1082】线段树练习重做
- codevs1081 线段树练习 2<区间修改>
- Codevs1082 线段树练习三(树状数组)
- codevs 1082 线段树练习3
- codevs 1082 线段树练习3 模板题
- Code Vs 1082 线段树练习 3
- codevs 1082 线段树练习 3
- 【CODEVS1082】线段树练习3
- 【codevs1082】线段树练习3——树状数组(改段求段)
- [树状数组]code[vs] 1082——线段树练习 3