CODEVS 1081 线段树练习 2
来源:互联网 发布:阿里云大厦 部门 编辑:程序博客网 时间:2024/05/16 15:15
题目描述 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 <bits/stdc++.h>#define N 100001int n,m;int a[N];int main(){ int t,x,y,z; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d",&t); if(t==1) { scanf("%d %d %d",&x,&y,&z); for(int j=x;j<=y;j++) a[j]=a[j]+z; } else { scanf("%d",&x); printf("%d\n",a[x]); } }}
线段树
#include <bits/stdc++.h>#define N 100005struct TREE{ int l,r,c,lazy;}t[N * 4];void build(int l,int r,int pos){ t[pos].l = l; t[pos].r = r; if (t[pos].l == t[pos].r) return ; int mid = (l + r) >> 1; build(l,mid,pos * 2); build(mid + 1,r,pos * 2 + 1);}void add(int num,int pos,int p){ if (t[p].l == t[p].r && t[p].r == pos) { t[p].c = num; return ; } int mid = (t[p].l + t[p].r) >> 1; if (pos > mid) add(num,pos,p * 2 + 1); else add(num,pos,p * 2);} void pushDown(int pos){ t[pos * 2 + 1].lazy += t[pos].lazy; t[pos * 2].lazy += t[pos].lazy; t[pos].lazy = 0;}void addSum(int l,int r,int c,int p){ if (t[p].l == l && t[p].r == r) { t[p].lazy += c; return ; } int mid = (t[p].l + t[p].r) >> 1; pushDown(p); if (l > mid) addSum(l,r,c,p * 2 + 1); else if (r <= mid) addSum(l,r,c,p * 2); else { addSum(l,mid,c,p * 2); addSum(mid + 1,r,c,p * 2 + 1); }}int find(int pos,int p){ if (t[p].l == t[p].r && t[p].r == pos) { return t[p].c + t[p].lazy; } pushDown(p); int mid = (t[p].l + t[p].r) >> 1; if (pos > mid) return find(pos,p * 2 + 1); else return find(pos,p * 2);}int main(){ int n,Q; scanf("%d",&n); build(1,n,1); for (int i = 1; i <= n; i++) { int x; scanf("%d",&x); add(x,i,1); } scanf("%d",&Q); for (int i = 1; i <= Q; i++) { int k; scanf("%d",&k); if (k == 1) { int x,y,z; scanf("%d%d%d",&x,&y,&z); addSum(x,y,z,1); } else { int pos; scanf("%d",&pos); printf("%d\n",find(pos,1)); } }}
树状数组
#include <bits/stdc++.h>int c[200000];int n,m,t,x,y,z;int lowbit(int x){ return x&-x;}void add(int x,int y){ while(x<=n) { c[x]=c[x]+y; x=x+lowbit(x); }}int getsum(int x){ int s=0; while(x>=1) { s=s+c[x]; x=x-lowbit(x); } return s;}int main(){ scanf("%d",&n); y=0; for(int i=1;i<=n;i++) { scanf("%d",&x); add(i,x-y); y=x; } scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d",&t); if(t==1) { scanf("%d %d %d",&x,&y,&z); add(x,z); add(y+1,-z); } else { scanf("%d",&x); printf("%d\n",getsum(x)); } }}
0 0
- CODEVS 1081线段树练习2
- CODEVS 1081 线段树练习 2
- 1081 线段树练习 2 codevs
- Codevs 1081 线段树练习2
- 【codevs 1081】线段树练习 2
- <线段树系列2> codevs 1082 线段树练习2
- codevs线段树练习3
- [codevs] 线段树练习4
- CODEVS 1080线段树练习
- 1080 线段树练习 codevs
- CODEVS 1080 线段树练习
- [Codevs] 1080 线段树练习
- 【codevs 1080】线段树练习
- Codevs 1081 线段树练习 2(线段树&&树状数组&&分块)
- 【codevs 1081】线段树练习2(单点查询+区间修改)
- CODEVS-1082-线段树练习3-splay
- 【codevs 1080~1082】线段树练习重做
- 【codevs 1082】线段树练习3
- 关于Android开发界面设计之去掉标题栏的方法
- 51nod-1191 消灭兔子(贪心)
- 数据库和表结构得一些基本常用命令总结
- python中base64模块的加解密函数
- Insert into a Cyclic Sorted List
- CODEVS 1081 线段树练习 2
- Merge Two Sorted Lists
- JavaScript在JSF框架中汉字乱码问题的解决方法
- test
- 浅谈angular优缺点
- 数据库连接池--C3P0连接池
- 数字图像基础---直方图修正
- Android 四种点击事件的方法
- C++中动态分配数组的分析