poj2892——Tunnel Warfare

本文介绍了一种基于线段树的数据结构实现,用于处理区间内的元素删除、查询及撤销操作。通过递归构建和更新线段树节点,能够高效地解决区间内元素的变化问题。该算法适用于在线算法竞赛中涉及区间操作的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

...(poj可过,hdu过不去,郁闷!)

#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define maxn 50005 int ans,n,m; int stack[maxn],top; class tree { public: int l,r,lx,rx; }; tree st[maxn*4]; void build(int index,int l,int r) { st[index].l=l;st[index].r=r; st[index].rx=r-l+1;st[index].lx=r-l+1; if(l==r) return ; int mid=((l+r)>>1); build(index*2,l,mid); build(index*2+1,mid+1,r); } void Delete(int index,int k) { if(k-st[index].l<st[index].lx) st[index].lx=k-st[index].l; if(st[index].r -k<st[index].rx ) st[index].rx=st[index].r-k; if(st[index].l==st[index].r ) return ; int mid=((st[index].r +st[index].l )>>1); if(k<=mid) Delete(index*2,k); else Delete(index*2+1,k); } void Research(int index,int k) { if(st[index].l ==st[index].r ) { if(st[index].lx!=0&&st[index].rx!=0) ans++; return ; } int mid=((st[index].l +st[index].r )>>1); if(k<=mid)//左边 { if(st[index*2].rx >=(mid-k+1)) ans+=st[index*2+1].lx; if(st[index*2].rx+st[index*2].lx >st[index*2].r-st[index*2].l+1) ans+=st[index*2].lx; else Research(index*2,k); } else { if(st[index*2+1].lx>=k-mid) ans+=st[index*2].rx ; if(st[index*2+1].rx+st[index*2+1].lx >st[index*2+1].r-st[index*2+1].l +1) ans+=st[index*2+1].lx ; else Research(index*2+1,k); } } void Repair(int index,int k) { if(st[index].l==st[index].r ) { st[index].lx=st[index].rx =1; return ; } int mid=((st[index].l+st[index].r)>>1); if(k<=mid) Repair(index*2,k); else Repair(index*2+1,k); st[index].lx=st[index*2].lx ; if(st[index].lx >=(mid-st[index].l +1)) st[index].lx +=(st[index*2+1].lx); st[index].rx =st[index*2+1].rx ; if(st[index].rx >=(st[index].r-mid)) st[index].rx +=(st[index*2].rx ); } int main() { char ch; int k; top=0; cin>>n>>m; build(1,1,n); for(int i=0;i<m;i++) { cin>>ch; if(ch=='D') { cin>>k; stack[top++]=k; Delete(1,k); } else if(ch=='Q') { cin>>k; ans=0; Research(1,k); cout<<ans<<endl; } else { k=stack[--top]; Repair(1,k); } } return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值