线段树(单点更新)
来源:互联网 发布:高考软件文科 编辑:程序博客网 时间:2024/05/18 10:23
1. hdu 1166 敌兵布阵
单点更新,区间求和,最裸的线段树
#include <cstdio>#include <iostream>#include <algorithm>using namespace std;#define maxn 50010#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1struct Tree{ int l,r,num;}tree[maxn<<2];void pushup(int rt){ tree[rt].num=tree[rt<<1].num+tree[rt<<1|1].num;}void build(int l,int r,int rt){ tree[rt].l=l; tree[rt].r=r; if(l==r){ scanf("%d",&tree[rt].num); return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt);}void update(int pos,int val,int rt){ int l,r; l=tree[rt].l; r=tree[rt].r; if(l==r){ tree[rt].num+=val; return ; } int m=(l+r)>>1; if(pos<=m) update(pos,val,rt<<1); else update(pos,val,rt<<1|1); pushup(rt);}int query(int x,int y,int rt){ int l,r; l=tree[rt].l; r=tree[rt].r; if(x==l && y==r){ return tree[rt].num; } int m=(l+r)>>1; int ans=0; if(y<=m) ans+=query(x,y,rt<<1); else if(m<x) ans+=query(x,y,rt<<1|1); else { ans+=query(x,m,rt<<1); ans+=query(m+1,y,rt<<1|1); } return ans;}int main(){ int T; scanf("%d",&T); for(int cas=1;cas<=T;cas++){ printf("Case %d:\n",cas); int n; scanf("%d",&n); build(1,n,1); char op[10]; int x,y; while(~scanf("%s",op)){ if(op[0]=='E') break; scanf("%d%d",&x,&y); if(op[0]=='A') update(x,y,1); else if(op[0]=='S') update(x,-y,1); else printf("%d\n",query(x,y,1)); } } return 0;}
2. hdu 1754 I Hate It
单点更新,区间求最值,裸线段树
#include <cstdio>#include <cstring>#include <iostream>#include <cmath>#include <algorithm>using namespace std;#define maxn 200010#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define inf 1<<31struct Tree{ int l,r,num;}tree[maxn<<2];void pushup(int rt){ tree[rt].num=max(tree[rt<<1].num,tree[rt<<1|1].num);}void build(int l,int r,int rt){ tree[rt].l=l; tree[rt].r=r; if(l==r){ scanf("%d",&tree[rt].num); return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt);}void update(int pos,int var,int rt){ int l,r; l=tree[rt].l; r=tree[rt].r; if(l==r){ tree[rt].num=var; return ; } int m=(l+r)>>1; if(pos<=m) update(pos,var,rt<<1); else update(pos,var,rt<<1|1); pushup(rt);}int query(int x,int y,int rt){ int l,r; l=tree[rt].l; r=tree[rt].r; if(l==x && y==r){ return tree[rt].num; } int m=(l+r)>>1; int ans=-inf; if(x<=m) ans=max(ans,query(x,min(m,y),rt<<1)); if(m<y) ans=max(ans,query(max(m+1,x),y,rt<<1|1)); return ans;}int main(){ int m,n; while(scanf("%d%d",&n,&m)!=EOF){ build(1,n,1); char op[10]; int x,y; while(m--){ scanf("%s%d%d",op,&x,&y); if(op[0]=='Q') printf("%d\n",query(x,y,1)); else update(x,y,1); } } return 0;}
3. hdu 1394 Minimum Inversion Number
求滚动之后,逆序对最少的对数,建一个节点值为0的线段树,每次插进去一个数之后,更新比他大的节点全部加1
#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define maxn 5050#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1struct Tree{ int l,r,num;}tree[maxn];int num[maxn];void pushup(int rt){ tree[rt].num=tree[rt<<1].num+tree[rt<<1|1].num;}void build(int l,int r,int rt){ tree[rt].l=l; tree[rt].r=r; tree[rt].num=0; if(l==r) return ; int m=(l+r)>>1; build(lson); build(rson);}void update(int pos,int rt){ int l=tree[rt].l; int r=tree[rt].r; tree[rt].num++; if(l==r) return ; int m=(l+r)>>1; if(pos<=m) update(pos,rt<<1); else update(pos,rt<<1|1);}int query(int x,int y,int rt){ int l=tree[rt].l; int r=tree[rt].r; if(x==l && y==r){ return tree[rt].num; } int ans=0; int m=(l+r)>>1; if(y<=m) ans+=query(x,y,rt<<1); else if(m<x) ans+=query(x,y,rt<<1|1); else { ans+=query(x,m,rt<<1); ans+=query(m+1,y,rt<<1|1); } return ans;}int main(){ int n; while(scanf("%d",&n)!=EOF){ build(1,n,1); int ans=0; for(int i=1;i<=n;i++){ scanf("%d",&num[i]); ans+=query(num[i]+1,n,1); update(num[i]+1,1); } int mx=ans; for(int i=1;i<=n;i++){ ans=ans-num[i]+n-1-num[i]; mx=min(mx,ans); } printf("%d\n",mx); } return 0;}
4. hdu 2795 billboard
广告牌,每层至多放总宽为w的广告,每次放的时候优先考虑最上面最左边的位置,问每次放的位置的排数,不能放输出-1
线段树初始值维护一个最大值,对于当前节点,能放就放然后节点值减小val,并更新到父亲节点。
#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <cmath>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define maxn 200010struct Tree{ int l,r,num;}tree[maxn<<2];int h,w,n;void pushup(int rt){ tree[rt].num=max(tree[rt<<1].num,tree[rt<<1|1].num);}void build(int l,int r,int rt){ tree[rt].l=l; tree[rt].r=r; if(l==r){ tree[rt].num=w; return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt);}int query(int val,int rt){ int l=tree[rt].l; int r=tree[rt].r; if(l==r){ if(tree[rt].num<val) return -1; else{ tree[rt].num-=val; return l; } } int ret; if(tree[rt<<1].num>=val) ret=query(val,rt<<1); else ret=query(val,rt<<1|1); pushup(rt); return ret;}int main(){ while(scanf("%d%d%d",&h,&w,&n)!=EOF){ h=min(h,n); build(1,h,1); int val; for(int i=1;i<=n;i++){ scanf("%d",&val); printf("%d\n",query(val,1)); } } return 0;}
5. CF 197div2 D. Xenia and Bit Operations
题意:求一排数字的位运算的结果,建好树之后从下往上,异或和或交替运算。
思路:距离叶子节点距离为奇数的节点操作为异或更新,距离为偶数的为或操作更新。
#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <cmath>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define maxn (1<<17)struct Tree{ int l,r,num,deep;}tree[(maxn<<2)+1];void pushup(int rt){ tree[rt].deep=tree[rt<<1].deep+1; if(tree[rt].deep&1) tree[rt].num=tree[rt<<1].num^tree[rt<<1|1].num; else tree[rt].num=tree[rt<<1].num|tree[rt<<1|1].num;}void build(int l,int r,int rt){ tree[rt].l=l; tree[rt].r=r; if(l==r){ tree[rt].deep=1; scanf("%d",&tree[rt].num); return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt);}void update(int pos,int val,int rt){ int l=tree[rt].l; int r=tree[rt].r; if(l==r){ tree[rt].num=val; return ; } int m=(l+r)>>1; if(pos<=m) update(pos,val,rt<<1); else update(pos,val,rt<<1|1); pushup(rt);}int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF){ build(1,(1<<n),1); int x,y; while(m--){ scanf("%d%d",&x,&y); update(x,y,1); printf("%d\n",tree[1].num); } } return 0;}
- 线段树(单点更新)
- 线段树(单点更新)
- 线段树(单点更新+区间更新)
- 线段树 单点更新
- 线段树单点更新
- 线段树 单点更新
- 单点更新线段树
- 线段树单点更新
- 线段树单点更新
- 线段树 单点更新
- 线段树 单点更新
- 线段树单点更新
- 线段树 单点更新
- 单点更新线段树
- 线段树单点更新
- 线段树,单点更新
- 线段树(单点更新)hdu1754
- 线段树(单点更新)poj2828
- 美丽的句子
- Boost智能指针——weak_ptr
- 从程序员到项目经理:认识项目经理
- 使用log4j记录日志
- [面试算法]减少中间变量的面试题
- 线段树(单点更新)
- 数据结构与算法实验题-战争来了
- 前Google人谈团队管理:针对不同员工的情境管理法和如何选择合理的团队规模
- panel 显示winform
- php 将对象转数组
- 职场菜鸟感想
- 东软实训推荐面试问题5:你对工作的期望与目标何在?
- apache-nutch-1.7-src.tar.gz 解压编译时无法从资源库下载jar包的问题
- 在MFC下调用WPF控件的总结