线段树
来源:互联网 发布:android 移动网络 编辑:程序博客网 时间:2024/06/03 10:04
线段树,好痛苦啊,都看了好几天,看别人的代码,当时是理解了,但是过两天又忘了,自己做题的时候还是不会写代码,难道数据结构就这么难吗?
我都不记得这是第几天了,这次稍微强一点,虽然参考了别人的代码,但总体上还是自己写的,写篇博客,以后不会了,看自己的就不算是参考别人的代码了,哈哈。。。。。。先把几个模块分清楚。
建树:
void build(int l ,int r,int root){ if(l == r) scanf("%d",&maxx[root]); else { int mid =(l + r) >>1; build(l,mid,root<<1); build(mid+1,r,root<<1 | 1); pushup(root); }}
pushup()函数:
void pushup(int root){ maxx[root] = max(maxx[root<<1],maxx[root<<1 | 1]);}
更新点:
void update(int p,int v,int l,int r,int root){ if(l == r) maxx[root] = v; else { int mid = (l + r)>> 1; if(p <= mid) update(p,v,l,mid,root<<1); else update(p,v,mid+1,r,root<<1 | 1); pushup(root); }}区间求最大值:
int getsum(int L,int R,int l,int r,int root){ if(L <= l && R >= r) return maxx[root]; else { int mid = (l + r)>>1; int ans = INF; if(L<=mid) ans = max(ans,getsum(L,R,l,mid,root<<1)); if(R > mid)ans = max(ans,getsum(L,R,mid+1,r,root<<1 | 1)); return ans; }}上面的模板,是以求最大值为原型写的,区间求和和它大同小异
http://acm.hdu.edu.cn/showproblem.php?pid=1166
#include<stdio.h>#include<iostream>using namespace std;#define INF -100000000;int sum[50010<<2];void build(int l ,int r,int root){ if(l == r) scanf("%d",&sum[root]); else { int mid =(l + r) >>1; build(l,mid,root<<1); build(mid+1,r,root<<1 | 1); sum[root] = sum[root <<1] + sum[root<<1 | 1]; }}void update(int p,int v,int l,int r,int root){ if(l == r) sum[root] += v; else { int mid = (l + r)>> 1; if(p <= mid) update(p,v,l,mid,root<<1); else update(p,v,mid+1,r,root<<1 | 1); sum[root] = sum[root<<1] + sum[root<<1 |1]; }}int getsum(int L,int R,int l,int r,int root){ if(L <= l && R >= r) return sum[root]; else { int mid = (l + r)>>1; int ans = 0; if(L<=mid) ans += getsum(L,R,l,mid,root<<1); if(R > mid)ans += getsum(L,R,mid+1,r,root<<1 | 1); return ans; }}int main(){ //freopen("1.txt","r",stdin); //freopen("2.txt","w",stdout); int T,n; char s[6]; scanf("%d",&T); int k = 1; while(T--) { printf("Case %d:\n",k++); scanf("%d",&n); build(1,n,1); while(~scanf("%s",s)) { if(s[0] == 'E')break; int a,b; scanf("%d%d",&a,&b); if(s[0] == 'Q') printf("%d\n",getsum(a,b,1,n,1)); else if(s[0] == 'A') update(a,b,1,n,1); else update(a,-b,1,n,1); } } return 0;}
单点替换,求区间最值:
http://acm.hdu.edu.cn/showproblem.php?pid=1754
#include<stdio.h>#include<iostream>#include<algorithm>using namespace std;#define INF -100000000;int maxx[200010<<2];void pushup(int root){ maxx[root] = max(maxx[root<<1],maxx[root<<1 | 1]);}void build(int l ,int r,int root){ if(l == r) scanf("%d",&maxx[root]); else { int mid =(l + r) >>1; build(l,mid,root<<1); build(mid+1,r,root<<1 | 1); pushup(root); }}void update(int p,int v,int l,int r,int root){ if(l == r) maxx[root] = v; else { int mid = (l + r)>> 1; if(p <= mid) update(p,v,l,mid,root<<1); else update(p,v,mid+1,r,root<<1 | 1); pushup(root); }}int getsum(int L,int R,int l,int r,int root){ if(L <= l && R >= r) return maxx[root]; else { int mid = (l + r)>>1; int ans = INF; if(L<=mid) ans = max(ans,getsum(L,R,l,mid,root<<1)); if(R > mid)ans = max(ans,getsum(L,R,mid+1,r,root<<1 | 1)); return ans; }}int main(){ //freopen("1.txt","r",stdin); //freopen("2.txt","w",stdout); int n,m; char s[6]; while(~scanf("%d%d",&n,&m)) { build(1,n,1); while(m--) { int a,b; scanf("%s%d%d",s,&a,&b); if(s[0] == 'Q') printf("%d\n",getsum(a,b,1,n,1)); else update(a,b,1,n,1); } } return 0;}
0 0
- 线段树?线段树!
- 线段树?线段树!
- 线段_线段树
- 线段_线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- Android中英文权限对照表(自己学习)
- .NET Framework 4.0的新特性
- 磁盘管理三之LVM
- PAT 1006
- 开张啦!
- 线段树
- DOS 连接本地MySQL 数据库
- appendReplacement appendTail组合使用。
- sizeof
- iOS NSUserDefaults 的简单用法
- mysql数据库报如下错误-----------com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data s
- CentOS下安装tar包/rpm包
- fcntl设置文件为close_on_exec
- Linux中yum手动安装、手动建立仓库文件夹关联实现关联包自动安装、yum相关命令使用