poj 3667 线段树(区间合并)

来源:互联网 发布:gamemaker 源码 编辑:程序博客网 时间:2024/06/13 21:21
#include<cstdio>#include<cstring>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define MAX(x,y) ((x)>(y)?(x):(y))#define MAX_N 50001int d[MAX_N<<2],L[MAX_N<<2],R[MAX_N<<2],T[MAX_N<<2];void build(int l,int r,int rt){d[rt]=-1;L[rt]=R[rt]=T[rt]=r-l+1;if(l==r)return ;int m=(l+r)>>1;build(lson);build(rson);}void pushup(int l,int r,int rt){L[rt]=L[rt<<1];R[rt]=R[rt<<1|1];int m=(l+r)>>1;if(L[rt]==(m-l+1))L[rt]+=L[rt<<1|1];if(R[rt]==(r-m))R[rt]+=R[rt<<1];T[rt]=MAX(MAX(T[rt<<1],T[rt<<1|1]),R[rt<<1]+L[rt<<1|1]);}void pushdown(int l,int r,int rt){int m=(l+r)>>1;if(d[rt]!=-1){d[rt<<1]=d[rt<<1|1]=d[rt];T[rt<<1]=L[rt<<1]=R[rt<<1]=d[rt]?0:(m-l+1);T[rt<<1|1]=L[rt<<1|1]=R[rt<<1|1]=d[rt]?0:(r-m);d[rt]=-1;}}int query(int k,int l,int r,int rt){if(l==r)return l;pushdown(l,r,rt); int m=(l+r)>>1;    if(T[rt<<1]>=k)    return query(k,lson);    else    {    if(R[rt<<1]+L[rt<<1|1]>=k)    return m-R[rt<<1]+1;    else    return query(k,rson);}  }void update(int a,int b,int v,int l,int r,int rt){if(a>r||b<l)return ;if(a<=l&&r<=b){T[rt]=L[rt]=R[rt]=v?0:(r-l+1);d[rt]=v;return ;}pushdown(l,r,rt);int m=(l+r)>>1;update(a,b,v,lson);update(a,b,v,rson);pushup(l,r,rt);}int main(){int n,q;scanf("%d%d",&n,&q);build(1,n,1);while(q--){int p,x,a,b;scanf("%d",&p);if(p==1){scanf("%d",&x);if(T[1]<x)printf("0\n");else{int lo=query(x,1,n,1);printf("%d\n",lo);update(lo,lo+x-1,1,1,n,1);}}else{scanf("%d%d",&a,&b);update(a,a+b-1,0,1,n,1);}}}

0 0
原创粉丝点击