hdu 1540 线段树(区间合并入门)

来源:互联网 发布:淘宝保证金信用账户 编辑:程序博客网 时间:2024/06/06 21:20

点击打开链接

#include <iostream>#include <cstring>#include <vector>using namespace std;typedef long long ll;const int N=5e4+20;int s[N];struct node{int l,r;int ls,rs,ms;//左端,右端,最大连续,ms区间最大连续 }a[N<<2]; void build(int l,int r,int rt){a[rt].l=l;a[rt].r=r;a[rt].ls=a[rt].rs=a[rt].ms=r-l+1;//if(l!=r){int mid=(l+r)>>1;build(l,mid,rt<<1);build(mid+1,r,rt<<1|1);} }void pushup(int rt){a[rt].ls=a[rt<<1].ls;//左区间等于从左子树左端开始a[rt].rs=a[rt<<1|1].rs;a[rt].ms=max(max(a[rt<<1].ms,a[rt<<1|1].ms),a[rt<<1].rs+a[rt<<1|1].ls);//左子树右端连续~右子树左端起连续 if(a[rt<<1].ls == a[rt<<1].r-a[rt<<1].l+1)//左子树区间满了的话,父亲左区间要加上右孩子的左区间      a[rt].ls += a[rt<<1|1].ls;      if(a[rt<<1|1].rs == a[rt<<1|1].r-a[rt<<1|1].l+1)//同理  a[rt].rs += a[rt<<1].rs;  } void update(int rt,int p,int op){if(a[rt].l==a[rt].r){if(op==1)a[rt].ls=a[rt].rs=a[rt].ms=1;//elsea[rt].ls=a[rt].rs=a[rt].ms=0;//return; }int mid=(a[rt].l+a[rt].r)>>1;if(p<=mid)//更新p所在的一段 update(rt<<1,p,op);elseupdate(rt<<1|1,p,op); pushup(rt);}int query(int rt,int p){if(a[rt].l==a[rt].r||a[rt].ms==0||a[rt].ms==a[rt].r-a[rt].l+1){return a[rt].ms; } int mid=(a[rt].l+a[rt].r)>>1;if(p<=mid)//查询p所在的哪一段 {if(p>=a[rt<<1].r-a[rt<<1].rs+1)//p在左子树右区间的内,和右子树可能有相接  {return query(rt<<1,p)+query(rt<<1|1,mid+1); }else{return query(rt<<1,p);}} else{if(p<=a[rt<<1|1].l+a[rt<<1|1].ls-1)//同理  {return query(rt<<1|1,p)+query(rt<<1,mid); }else{return query(rt<<1|1,p);}}} int main(){int n,m;while(cin>>n>>m){build(1,n,1); int x;int top=0;while(m--){char op[2];scanf("%s",op);if(op[0]=='D'){scanf("%d",&x);s[top++]=x;update(1,x,0);//0:del }else if(op[0]=='Q'){scanf("%d",&x);printf("%d\n",query(1,x));}else{if(x>0){x=s[--top];update(1,x,1);//1:restore}}}}return 0;}


0 0
原创粉丝点击