线段树最全模板
来源:互联网 发布:好友生日提醒软件 编辑:程序博客网 时间:2024/06/14 14:25
一定要做的线段树习题汇总
一、模板
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define MAXN 200010#define lson l,mid,p<<1#define rson mid+1,r,p<<1|1int sum[MAXN<<2];void pushUp(int p){ sum[p]=max(sum[p<<1],sum[p<<1|1]);}void build(int l,int r,int p){ if(l==r){ scanf("%d",&sum[p]); return ; } int mid=(l+r)>>1; build(lson); build(rson); pushUp(p);}int query(int l,int r,int p,int a,int b){ if(l>=a&&b>=r) //根据功能代码修改部分 return sum[p]; int ans=0; int mid=(l+r)>>1; if(mid>=a) ans=max(ans,query(lson,a,b)); //根据功能代码修改部分 if(mid<b) ans=max(ans,query(rson,a,b)); return ans;}void update(int l,int r,int p,int a,int b){ if(l==r){//根据功能代码修改部分
sum[p]=b; return ; } int mid=(l+r)>>1; if(a<=mid) update(lson,a,b); else update(rson,a,b); pushUp(p);}int main(){ int n,m; char ch[5]; //freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&m)) { int a,b; build(1,n,1); while(m--) { scanf("%s%d%d",ch,&a,&b); if(ch[0]=='Q') printf("%d\n",query(1,n,1,a,b)); else update(1,n,1,a,b); } } return 0;}二、区间查询,无单点更新
#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn=200010;int sum[maxn<<2];//数组开四倍int h,w,n;//p表示下标void pushUp(int p){ //p表示下标,赋值为两个儿子中的最大值 sum[p]=max(sum[p<<1],sum[p<<1|1]);}//建树void build(int l,int r,int p){ if(l==r)//区间长度为0时结束递归 { sum[p]=w; return ; } //否则的话,分别递归左儿子和右儿子 int mid=(r+l)>>1; build(l,mid,p<<1); build(mid+1,r,p<<1|1); pushUp(p);}//区间查询//线段树的最高顶点是表示所有行里面最大的宽度int query(int l,int r,int p,int num){ if(l==r)//找到了一个完全重合的区间 { sum[p]-=num;//进行对应的查询操作 return l; } int ans; int mid=(r+l)>>1;//下面要注意,先保存ans,然后更新值后再返回 if(sum[p<<1]>=num) { ans=query(l,mid,p<<1,num); } else { ans=query(mid+1,r,p<<1|1,num); } pushUp(p); return ans;}int main(){ while(scanf("%d%d%d",&h,&w,&n)!=EOF) { memset(sum,0,sizeof(sum)); if(h>n)h=n; int temp; build(1,h,1);//建树区间为[1,h],下标开始序号为1 for(int i=0;i<n;i++) { scanf("%d",&temp); if(sum[1]<temp) cout<<"-1"<<endl; else cout<<query(1,h,1,temp)<<endl; } } return 0;}
三、单点更新+区间求和
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define MAXN 50010#define lson l,mid,p<<1#define rson mid+1,r,p<<1|1#define mem(a) memset(a,0,sizeof(a[0]))int sum[MAXN<<2];void pushUp(int p){ sum[p]=sum[p<<1]+sum[p<<1|1];}void build(int l,int r,int p){ if(l==r){ scanf("%d",&sum[p]); return; } int mid=(l+r)>>1; build(lson); build(rson); pushUp(p);}int query(int l,int r,int p,int i,int j){ if(l>=i&&r<=j){ return sum[p]; } int ans=0; int mid=(l+r)>>1; if(mid<j) ans+=query(rson,i,j); if(mid>=i) ans+=query(lson,i,j); return ans;}void update(int l,int r,int p,int i,int j){ if(l==r){ sum[p]+=j; return ; } int mid=(l+r)>>1; if(mid>=i) update(lson,i,j); else update(rson,i,j); pushUp(p);}int main(){ int n,T; int cases=1; char str[10]; //freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { mem(sum); scanf("%d",&n); printf("Case %d:\n",cases++); int i,j; build(1,n,1); while(scanf("%s",str)&&strcmp(str,"End")) { scanf("%d%d",&i,&j); if(strcmp(str,"Query")==0) printf("%d\n",query(1,n,1,i,j)); else if(strcmp(str,"Add")==0) update(1,n,1,i,j); else if(strcmp(str,"Sub")==0) update(1,n,1,i,-j); } } return 0;}四、区间查询最值+单点更新
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define MAXN 200010#define lson l,mid,p<<1#define rson mid+1,r,p<<1|1int sum[MAXN<<2];void pushUp(int p){ sum[p]=max(sum[p<<1],sum[p<<1|1]);}void build(int l,int r,int p){ if(l==r){ scanf("%d",&sum[p]); return ; } int mid=(l+r)>>1; build(lson); build(rson); pushUp(p);}int query(int l,int r,int p,int a,int b){ if(l>=a&&b>=r) return sum[p]; int ans=0; int mid=(l+r)>>1; if(mid>=a) ans=max(ans,query(lson,a,b)); if(mid<b) ans=max(ans,query(rson,a,b)); return ans;}void update(int l,int r,int p,int a,int b){ if(l==r){ sum[p]=b; return ; } int mid=(l+r)>>1; if(a<=mid) update(lson,a,b); else update(rson,a,b); pushUp(p);}int main(){ int n,m; char ch[5]; //freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&m)) { int a,b; build(1,n,1); while(m--) { scanf("%s%d%d",ch,&a,&b); if(ch[0]=='Q') printf("%d\n",query(1,n,1,a,b)); else update(1,n,1,a,b); } } return 0;}
阅读全文
0 0
- 线段树最全模板
- ACM 线段树模板(模板)
- 线段树模板
- hdu_1166_线段树模板
- 线段树模板
- 线段树模板 poj2777
- 线段树模板
- 线段相交模板
- 线段树模板
- 线段树-模板
- 线段树模板
- 线段树模板
- 线段树模板
- 【模板】线段相交
- Hdu1166-- 线段树模板
- 线段树模板
- 线段树模板
- 线段树模板
- 欢迎使用CSDN-markdown编辑器
- Navi.Soft31.开发工具(含下载地址)
- CentOS 6源码编译安装Xen4.6
- ns2仿真学习(一)-tracer分析
- Flume初体验
- 线段树最全模板
- 1812. 【提高组NOIP2008】双栈排序 (twostack.pas/c/cpp)
- yum练习
- 抽奖大转盘 js
- nginx 操作和各种配置参考资料
- jenkins自动部署
- JavaScript console 获取title
- Boost.Python:安装使用(兼具Boost.Python库中Python编译版本的修改)
- 视觉SLAM融合IMU问题研究笔记