数据结构--M - 秋实大哥与线段树(单点更新与区间查询)
2015-04-18 01:21
344 查看
M - 秋实大哥与线段树
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)Submit Status
“学习本无底,前进莫徬徨。” 秋实大哥对一旁玩手机的学弟说道。
秋实大哥是一个爱学习的人,今天他刚刚学习了线段树这个数据结构。
为了检验自己的掌握程度,秋实大哥给自己出了一个题,同时邀请大家一起来作。
秋实大哥的题目要求你维护一个序列,支持两种操作:一种是修改某一个元素的值;一种是询问一段区间的和。
Input
第一行包含一个整数n,表示序列的长度。接下来一行包含n个整数ai,表示序列初始的元素。
接下来一行包含一个整数m,表示操作数。
接下来m行,每行是以下两种操作之一:
1 x v : 表示将第x个元素的值改为v 2 l r : 表示询问[l,r]这个区间的元素和
1≤n,m,v,ai≤100000,1≤l≤r≤n。
Output
对于每一个2 l r操作,输出一个整数占一行,表示对应的答案。Sample input and output
Sample Input | Sample Output |
---|---|
3 1 2 3 3 2 1 2 1 1 5 2 1 2 | 3 7 |
这道题是一道裸裸的线段树的单点更新与区间查询[l,r]sum的问题.
直接套用线段树的模板就可以了,但是要注意long long ,,,因为a_i<=10^5,n<=10^5,且a_i*n<=10^10 > 2*10^9。
代码:
# include<cstdio> # include<iostream> # include<fstream> # include<algorithm> # include<functional> # include<cstring> # include<string> # include<cstdlib> # include<iomanip> # include<numeric> # include<cctype> # include<cmath> # include<ctime> # include<queue> # include<stack> # include<list> # include<set> # include<map> using namespace std; const double PI=4.0*atan(1.0); typedef long long LL; typedef unsigned long long ULL; # define inf 999999999 # define MAX 100004 struct Segtree { int left, right; LL sum; }tree[MAX*4]; int a[MAX]; void build ( int id,int l,int r ) { tree[id].left = l; tree[id].right = r; if ( l==r ) { scanf("%lld",&tree[id].sum); return; } else { int mid = (l+r)>>1; build(id<<1,l,mid); build(id<<1|1,mid+1,r); tree[id].sum = tree[id<<1].sum+tree[id<<1|1].sum; } } void updata( int id,int pos,int val ) { if ( tree[id].left==tree[id].right ) { tree[id].sum = val; } else { int mid = ( tree[id].left+tree[id].right )>>1; if ( pos <= mid ) { updata( id<<1,pos,val ); } else { updata( id<<1|1,pos,val ); } tree[id].sum = tree[id<<1].sum+tree[id<<1|1].sum; } } LL query( int id,int l,int r ) { if ( tree[id].left==l&&tree[id].right==r ) { return tree[id].sum; } else { int mid = ( tree[id].left+tree[id].right )>>1; if ( r <= mid ) { query( id<<1,l,r ); } else if ( l > mid ) { query( id<<1|1,l,r ); } else { return query( id<<1,l,mid)+query( id<<1|1,mid+1,r ); } } } int main(void) { int n; while ( cin>>n ) { memset(tree,0,sizeof(tree)); build(1,1,n); int t;cin>>t; while ( t-- ) { int t1,a,b; cin>>t1>>a>>b; if ( t1==1 ) { updata(1,a,b); } else { cout<<query(1,a,b)<<endl; } } } return 0; }
第二种写法:
区别就是对于原数组的处理,感觉第二种更能接受一点。
# include<cstdio> # include<iostream> # include<fstream> # include<algorithm> # include<functional> # include<cstring> # include<string> # include<cstdlib> # include<iomanip> # include<numeric> # include<cctype> # include<cmath> # include<ctime> # include<queue> # include<stack> # include<list> # include<set> # include<map> using namespace std; const double PI=4.0*atan(1.0); typedef long long LL; typedef unsigned long long ULL; # define inf 999999999 # define MAX 100004 struct Segtree { int left, right; LL sum; }tree[MAX*4]; LL a[MAX]; void build ( int id,int l,int r ) { tree[id].left = l; tree[id].right = r; if ( l==r ) { tree[id].sum = a[l]; return; } else { int mid = (l+r)>>1; build(id<<1,l,mid); build(id<<1|1,mid+1,r); tree[id].sum = tree[id<<1].sum+tree[id<<1|1].sum; } } void updata( int id,int pos,int val ) { if ( tree[id].left==tree[id].right ) { tree[id].sum = val; } else { int mid = ( tree[id].left+tree[id].right )>>1; if ( pos <= mid ) { updata( id<<1,pos,val ); } else { updata( id<<1|1,pos,val ); } tree[id].sum = tree[id<<1].sum+tree[id<<1|1].sum; } } LL query( int id,int l,int r ) { if ( tree[id].left==l&&tree[id].right==r ) { return tree[id].sum; } else { int mid = ( tree[id].left+tree[id].right )>>1; if ( r <= mid ) { query( id<<1,l,r ); } else if ( l > mid ) { query( id<<1|1,l,r ); } else { return query( id<<1,l,mid)+query( id<<1|1,mid+1,r ); } } } int main(void) { int n; while ( cin>>n ) { for ( int i = 1;i <= n;i++ ) { scanf("%lld",&a[i]); } memset(tree,0,sizeof(tree)); build(1,1,n); int t;cin>>t; while ( t-- ) { int t1,a,b; cin>>t1>>a>>b; if ( t1==1 ) { updata(1,a,b); } else { cout<<query(1,a,b)<<endl; } } } return 0; }
相关文章推荐
- 2015 UESTC 数据结构专题A题 秋实大哥与小朋友 线段树 区间更新,单点查询,离散化
- cdoj 1061 秋实大哥与战争 线段树,合并区间,单点更新,单点查询区间长度
- 2015 UESTC 数据结构专题D题 秋实大哥与战争 变化版本的线段树,合并区间,单点查询
- 2015 UESTC 数据结构专题B题 秋实大哥与花 线段树 区间加,区间查询和
- UESTC 1057 秋实大哥与花 线段树模板 区间更新+查询
- 线段树 (更新区间查询点)秋实大哥与小朋友
- CDOJ1073-秋实大哥与线段树 线段树单点更新+区间求和
- ACdream 1427—— Nice Sequence——————【线段树单点更新,区间查询】
- Codeforces 525B. Pasha and String【线段树 区间更新 单点查询】
- POJ 2155 Matrix (二维线段树入门,成段更新,单点查询 / 二维树状数组,区间更新,单点查询)
- hdoj 4819 Mosaic 【二维线段树 单点更新 区间查询】
- HDU 1540Tunnel Warfare Tunnel Warfare (线段树- 区间合并-单点更新查询)
- nyoj116 士兵杀敌(二)(线段树的区间查询和单点更新)
- hdu1166(线段树单点更新区间查询)
- HDU 1166 敌兵布阵-线段树-(单点更新,区间查询)
- HDU5861 (线段树区间更新+单点查询)
- hdu 5861 (线段树,区间更新,单点查询)
- ZOJ 5638——Prime Query——————【线段树区间更新,区间查询,单点更新】
- Flipping Parentheses (线段树 单点更新 区间查询)
- 【单点更新,区间查询,线段树】【HDU1166】【敌兵布阵】