hdu 1540 Tunnel Warfare(单点更新,区间合并)
来源:互联网 发布:macbook 软件下载 编辑:程序博客网 时间:2024/04/30 15:12
题意:给你n连成一条线的点,m个操作。D x把第x个村庄破坏,Q x查询与第x个村庄直接和间接相连的村庄数目(包括它自己),R把最早破坏的一个村庄恢复。
除了下面的另一种方法外,现在再做的时候,想到了另一种方法,在查询的时候,更新查找到的范围的左右端点。
/*代码风格更新后*/#include <iostream>#include <cstdio>#include <cstring>#include <stack>using namespace std;#define LL(x) (x<<1)#define RR(x) (x<<1|1)#define MID(a,b) (a+((b-a)>>1))const int N=50005;struct node{int lft,rht;int lmx,rmx;int len(){return rht-lft+1;}int mid(){return MID(lft,rht);}void init(){lmx=rmx=len();}void fun(int valu){if(valu==-1) lmx=rmx=0;else lmx=rmx=1;}};int n,m;struct Segtree{node tree[N*4];void up(int ind){tree[ind].lmx=tree[LL(ind)].lmx;tree[ind].rmx=tree[RR(ind)].rmx;if(tree[LL(ind)].lmx==tree[LL(ind)].len())tree[ind].lmx+=tree[RR(ind)].lmx;if(tree[RR(ind)].rmx==tree[RR(ind)].len())tree[ind].rmx+=tree[LL(ind)].rmx;}void build(int lft,int rht,int ind){tree[ind].lft=lft,tree[ind].rht=rht;tree[ind].init();if(lft!=rht){int mid=tree[ind].mid();build(lft,mid,LL(ind));build(mid+1,rht,RR(ind));}}void updata(int pos,int ind,int valu){if(tree[ind].lft==tree[ind].rht) tree[ind].fun(valu);else{int mid=tree[ind].mid();if(pos<=mid) updata(pos,LL(ind),valu);else updata(pos,RR(ind),valu);up(ind);}}void query(int pos,int ind,int& x,int& y){if(tree[ind].lft==tree[ind].rht){if(tree[ind].lmx==1) x=y=tree[ind].lft;else x=y=0;}else{int mid=tree[ind].mid();if(pos<=mid) query(pos,LL(ind),x,y);else query(pos,RR(ind),x,y);if(tree[LL(ind)].rht==y) y+=tree[RR(ind)].lmx;if(tree[RR(ind)].lft==x) x-=tree[LL(ind)].rmx;}}}seg;int main(){while(scanf("%d%d",&n,&m)!=EOF){stack<int> q;seg.build(1,n,1);while(m--){char cmd[5];int pos,st,ed;scanf("%s",cmd);if(cmd[0]=='D'){scanf("%d",&pos);seg.updata(pos,1,-1);q.push(pos);}else if(cmd[0]=='Q'){scanf("%d",&pos);seg.query(pos,1,st,ed);if(st==0&&ed==0) puts("0");else printf("%d\n",ed-st+1);//cout<<st<<" "<<ed<<endl;}else{seg.updata(q.top(),1,1); q.pop();}}}return 0;}
题目没有说有多组数据,不过却有多组数据,晕死。和hotel那题比较相似,在查询的时候要注意,要先查询是否在父区间的左端点的和右端点连续的范围内,然后查询是否在左右子区间的连接处。而不是查询是否在左子区间的左端点的连续的范围内,这样会出现错误。因为有一种情况是父区间的连续范围超过了中点。
/*代码风格更新前*/#include <iostream>#include <cstdio>#include <stack>using namespace std;const int N=50005;struct node{ int left,right; int lmax,rmax; int mid(){return left+(right-left)/2;} int dis(){return right-left+1;}};struct Segtree{ node tree[N*4]; void build(int left,int right,int r) { tree[r].left=left; tree[r].right=right; tree[r].lmax=tree[r].rmax=tree[r].dis(); if(left<right) { int mid=tree[r].mid(); build(left,mid,r*2); build(mid+1,right,r*2+1); } } void updata(int pos,int r,int co) { if(tree[r].left==tree[r].right) tree[r].lmax=tree[r].rmax=co; else { int mid=tree[r].mid(); if(pos<=mid) updata(pos,r*2,co); else if(pos>mid) updata(pos,r*2+1,co); tree[r].lmax=tree[r*2].lmax; tree[r].rmax=tree[r*2+1].rmax; if(tree[r*2].lmax==tree[r*2].dis()) tree[r].lmax+=tree[r*2+1].lmax; if(tree[r*2+1].rmax==tree[r*2+1].dis()) tree[r].rmax+=tree[r*2].rmax; } } int query(int pos,int r) { if(tree[r].left==tree[r].right) return tree[r].lmax; else { int mid=tree[r].mid(); if(tree[r].lmax+tree[r].left>pos) return tree[r].lmax; else if(tree[r*2+1].lmax+tree[r*2+1].left>pos&&tree[r*2].right-tree[r*2].rmax<pos)return tree[r*2].rmax+tree[r*2+1].lmax; else if(tree[r].right-tree[r].rmax<pos) return tree[r].rmax; else if(pos<=mid) return query(pos,r*2); else return query(pos,r*2+1); } }}seg;int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF) { stack<int> q; seg.build(1,n,1); for(int i=0;i<m;i++) { int a; char cmd[5]; scanf("%s",cmd); if(cmd[0]=='D') { scanf("%d",&a); seg.updata(a,1,0); q.push(a); } else if(cmd[0]=='Q') { scanf("%d",&a); printf("%d\n",seg.query(a,1)); } else { seg.updata(q.top(),1,1); q.pop(); } } } return 0;}
- hdu 1540 Tunnel Warfare(单点更新,区间合并)
- HDU 1540 Tunnel Warfare(单点更新,区间合并)
- HDU 1540Tunnel Warfare Tunnel Warfare (线段树- 区间合并-单点更新查询)
- HDU 1540 Tunnel Warfare(线段树 区间合并 +单点更新)
- HDU 1540——Tunnel Warfare(线段树,区间合并+单点更新+单点查询)
- HDU 1540 Tunnel Warfare(线段树单点更新+区间合并)
- hdu 1540 Tunnel Warfare(线段树单点更新+区间合并)
- hdu 1540 Tunnel Warfare(线段树——单点更新+区间合并)
- hdu 1540 Tunnel Warfare 线段树 单点更新,查询区间长度,区间合并
- HDU 1540 Tunnel Warfare(区间合并)
- hdu 1540 Tunnel Warfare(区间合并)
- hdu 1540 Tunnel Warfare(单点更新,取最大连续区间)★
- hdu1540 Tunnel Warfare--单点更新查询 & 区间合并
- 【Hdu】1540 Tunnel Warfare(线段树|区间合并)
- HDU 1540 Tunnel Warfare(线段树区间合并)
- HDU 1540 Tunnel Warfare (线段树区间合并)
- hdu 1540 Tunnel Warfare (线段树区间合并)
- HDU 1540 Tunnel Warfare (线段树,区间合并)
- 百度与谷歌有什么不同:产品经理文化与工程师文化
- postgreSQL导入excel文件
- C++虚函数表解析(转) ——写的真不错,忍不住转了
- 用C++实现的一种插件体系结构-----概述
- asp网页自动刷新总结
- hdu 1540 Tunnel Warfare(单点更新,区间合并)
- 大数运算——加法,减法,乘法
- Error: template argument uses local type
- 多线程和多进程的区别
- 机器学习正在改变我们的工作与生活
- Brackets Sequence
- csdn经常卡,在博客园开了博客
- llvm安装过程问题
- 程序语言发展简述