线段树(单点修改,区间查询)
2017-08-04 16:16
716 查看
/* * 线段树模板 * 单点修改,区间查询 */ #include<iostream> #include<cstdio> using namespace std; typedef long long LL; const int MAXN=1e5+5;// const int INF=0x3f3f3f3f;//根据是否超long long修改 int a[MAXN]; //线段树节点结构体 struct Node{ int left,right;//左右边界 int mi,ma;//最小值 最大值 LL sum;//和 }tree[MAXN*4];//空间开四倍 //向上更新 void PushUp(int rt){ tree[rt].mi=min(tree[rt<<1].mi,tree[rt<<1|1].mi); tree[rt].ma=max(tree[rt<<1].ma,tree[rt<<1|1].ma); tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum; } //建立函数 void Build(int rt,int L,int R){ tree[rt].left=L;tree[rt].right=R; if(L==R) {tree[rt].sum=tree[rt].mi=tree[rt].ma=a[L]; return;} int mid=(tree[rt].left+tree[rt].right)>>1; Build(rt<<1,L,mid);//只有Build时LR才会变 Build(rt<<1|1,mid+1,R); PushUp(rt); } LL QuerySum(int rt,int L,int R){ if(L<=tree[rt].left&&tree[rt].right<=R) return tree[rt].sum;//贡献为tree[rt].sum int mid=(tree[rt].left+tree[rt].right)>>1; LL res=0; if(L<=mid) res+=QuerySum(rt<<1,L,R); if(R>mid) res+=QuerySum(rt<<1|1,L,R); return res; } int QueryMin(int rt,int L,int R){ if(L<=tree[rt].left&&tree[rt].right<=R) return tree[rt].mi; int mid=(tree[rt].left+tree[rt].right)>>1; int res=INF; if(L<=mid) res=min(res,QueryMin(rt<<1,L,R)); if(R>mid) res=min(res,QueryMin(rt<<1|1,L,R)); return res; } int QueryMax(int rt,int L,int R){ if(L<=tree[rt].left&&tree[rt].right<=R) return tree[rt].ma;//完全包含才产生贡献 int mid=(tree[rt].left+tree[rt].right)>>1; int res=-INF; if(L<=mid) res=max(res,QueryMax(rt<<1,L,R)); if(R>mid) res=max(res,QueryMax(rt<<1|1,L,R)); return res; } void Update(int rt,int pos,int x){//把pos位的值改为x if(tree[rt].left==tree[rt].right) { tree[rt].sum=tree[rt].mi=tree[rt].ma=x; return; } int mid=(tree[rt].left+tree[rt].right)>>1; if(pos<=mid) Update(rt<<1,pos,x); else Update(rt<<1|1,pos,x); PushUp(rt); } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++) scanf("%d",&a[i]); Build(1,1,n);//建立线段树 int op,x,y; for(int i=1;i<=m;i++){ scanf("%d%d%d",&op,&x,&y); if(op==1){//询问[x,y]的和 printf("%lld\n",QuerySum(1,x,y)); }else if(op==2){//询问[x,y]的最大值 printf("%d\n",QueryMax(1,x,y)); }else if(op==3){//询问[x,y]的最小值 printf("%d\n",QueryMin(1,x,y)); }else{//修改第x位的值为y Update(1,x,y); } } } return 0; } /* 6 4 1 2 3 4 5 6 4 3 8 1 1 6 2 1 6 3 1 6 */
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define lson (rt<<1) #define rson (rt<<1|1) #define lowbit(x) ((x)&(-(x))) using namespace std; typedef long long LL; const int MAXN=2e5+5; int val[MAXN]; struct node { int ma,left,right; }tree[MAXN*4]; void pushup(int rt) { tree[rt].ma=max(tree[lson].ma,tree[rson].ma); } void build(int rt,int left,int right) { tree[rt].left=left; tree[rt].right=right; if(left==right) {tree[rt].ma=val[left];return;} int mid=(left+right)>>1; build(lson,left,mid); build(rson,mid+1,right); pushup(rt); } int query(int rt,int left,int right) { if(left<=tree[rt].left&&tree[rt].right<=right) return tree[rt].ma; int m=(tree[rt].left+tree[rt].right)>>1; int res=0; if(left<=m) res=max(res,query(lson,left,right)); if(right>m) res=max(res,query(rson,left,right)); return res; } void update(int rt,int pos,int val) { if(tree[rt].left==tree[rt].right) {tree[rt].ma=val;return;} int m=(tree[rt].left+tree[rt].right)>>1; if(pos<=m) update(lson,pos,val); else update(rson,pos,val); pushup(rt); } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;++i) scanf("%d",&val[i]); build(1,1,n); for(int i=1;i<=m;++i) { getchar(); char op;int x,y; scanf("%c",&op); scanf("%d%d",&x,&y); if(op=='Q') { printf("%d\n",query(1,x,y)); }else { update(1,x,y); } } } return 0; }
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define mem(a,b) memset(a,b,sizeof(a)) #define lson rt<<1 #define rson rt<<1|1 using namespace std; typedef long long LL; const int INF=0x3f3f3f3f; const double eps=1e-10; const int MAXN=1e5+5; const int MOD=1e9+7; int a[MAXN]; int minv[MAXN*4]; void build(int l,int r,int rt) { if(l==r) {minv[rt]=a[l];return;} int m=l+(r-l)/2; build(l,m,rt*2); build(m+1,r,rt*2+1); minv[rt]=min(minv[rt*2],minv[rt*2+1]); } int query(int o,int L,int R,int ql,int qr) { int M=L+(R-L)/2,ans=INF; if(ql<=L&&R<=qr) return minv[o];//当前结点完全包含在查询区间内 if(ql<=M) ans=min(ans,query(o*2,L,M,ql,qr));//往左走 if(M<qr) ans=min(ans,query(o*2+1,M+1,R,ql,qr));//往右走 return ans; } void update(int o,int L,int R,int p,int v)//修改A[p]=v { int M=L+(R-L)/2; if(L==R) minv[o]=v;//叶结点,直接更新minv else { if(p<=M) update(o*2,L,M,p,v); else update(o*2+1,M+1,R,p,v); minv[o]=min(minv[o*2],minv[o*2+1]); } } int main() { int T; scanf("%d",&T); while(T--) { int n;scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%d",&a[i]); } build(1,n,1); int q; scanf("%d",&q); int op,x,y; for(int i=1;i<=q;++i) { cin>>op>>x>>y; if(op==1) { update(1,1,n,x,y); }else if(op==2) { cout<<query(1,1,n,x,y)<<endl; } } } return 0; } /* 10 10 1 2 3 4 5 6 7 8 9 10 100 1 1 2 */
相关文章推荐
- 【codevs 1081】线段树练习2(单点查询+区间修改)
- HDU 1166 敌兵布阵 <线段树 单点修改 区间查询>
- Tallest Cow POJ - 3263(线段树区间修改,单点查询)
- POJ 3321 Apple Tree(DFS序+线段树单点修改区间查询)
- HDU3974 线段树区间修改单点查询+树上dfs序
- UVA - 12299 RMQ with Shifts (线段树:单点修改,区间查询)
- POJ 2155 Matrix 二维线段树 区间修改 单点查询
- 【算法系列学习】线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵
- BZOJ-1036: [ZJOI2008]树的统计Count (树链剖分 线段树 单点修改 区间查询 入门题)
- HDU 5861 Road(线段树 区间修改 单点查询)
- 树套树:二维线段树初步:hdu1823——Luck and Love(单点修改,区间查询)
- poj 3264 Balanced Lineup(线段树单点修改区间查询)
- poj2886线段树(单点修改,区间查询)
- (HDU 1754)I Hate It 线段树区间查询入门,单点修改
- 考试 线段树二分+单点修改+区间查询
- 1080 线段树练习 单点修改及区间查询
- 【数据结构】【线段树】单点修改区间查询
- HDU1166_敌兵布阵_线段树单点修改区间查询
- HDU1166 线段树 单点修改、区间查询
- hdu 5381 The sum of gcd(线段树等差数列区间修改+单点查询)