poj3667 线段树+区间合并

来源:互联网 发布:美洽电脑软件下载 编辑:程序博客网 时间:2024/04/27 15:58

第一道额~~

#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int MAXN=100005;struct node{    int l,r;    int lsum,rsum,msum;    int mid()    {        return (l+r)>>1;    }};node tree[MAXN*4];inline void pushup(int pos){    tree[pos].msum=max(tree[pos<<1].msum,tree[pos<<1|1].msum);    tree[pos].msum=max(tree[pos].msum,tree[pos<<1].rsum+tree[pos<<1|1].lsum);    if(tree[pos<<1].lsum==tree[pos<<1].r-tree[pos<<1].l+1)        tree[pos].lsum=tree[pos<<1].lsum+tree[pos<<1|1].lsum;    else        tree[pos].lsum=tree[pos<<1].lsum;    if(tree[pos<<1|1].rsum==tree[pos<<1|1].r-tree[pos<<1|1].l+1)        tree[pos].rsum=tree[pos<<1|1].rsum+tree[pos<<1].rsum;    else        tree[pos].rsum=tree[pos<<1|1].rsum;}inline void pushdown(int pos){    if(tree[pos].msum==tree[pos].r-tree[pos].l+1)    {        tree[pos<<1].msum=tree[pos<<1].lsum=tree[pos<<1].rsum=tree[pos<<1].r-tree[pos<<1].l+1;        tree[pos<<1|1].msum=tree[pos<<1|1].lsum=tree[pos<<1|1].rsum=tree[pos<<1|1].r-tree[pos<<1|1].l+1;    }    else if(tree[pos].msum==0)    {        tree[pos<<1].msum=tree[pos<<1].lsum=tree[pos<<1].rsum=0;        tree[pos<<1|1].msum=tree[pos<<1|1].lsum=tree[pos<<1|1].rsum=0;    }}void build(int l,int r,int pos){    tree[pos].l=l;    tree[pos].r=r;    if(l==r)    {        tree[pos].msum=tree[pos].lsum=tree[pos].rsum=1;        return ;    }    int mid=tree[pos].mid();    build(l,mid,pos<<1);    build(mid+1,r,pos<<1|1);    pushup(pos);}void update(int l,int r,int x,int pos){    if(tree[pos].l==l&&tree[pos].r==r)    {        if(x==0)            tree[pos].msum=tree[pos].lsum=tree[pos].rsum=                tree[pos].r-tree[pos].l+1;        else            tree[pos].msum=tree[pos].lsum=tree[pos].rsum=0;        return ;    }    pushdown(pos);    int mid=tree[pos].mid();    if(r<=mid)        update(l,r,x,pos<<1);    else if(l>mid)        update(l,r,x,pos<<1|1);    else    {        update(l,mid,x,pos<<1);        update(mid+1,r,x,pos<<1|1);    }    pushup(pos);}int query(int x,int pos){    if(tree[pos].msum<x)        return 0;    if(tree[pos].l==tree[pos].r)    {        return tree[pos].l;    }    if(tree[pos].lsum>=x)        return tree[pos].l;    pushdown(pos);    if(tree[pos<<1].msum>=x)        return query(x,pos<<1);    else if(tree[pos<<1].rsum+tree[pos<<1|1].lsum>=x)    {        return tree[pos<<1].r-tree[pos<<1].rsum+1;    }    else        return query(x,pos<<1|1);}int main(){    int n,m;    scanf("%d%d",&n,&m);    build(1,n,1);    int i;    for(i=0;i<m;i++)    {        int k,a,b;        scanf("%d",&k);        if(k==1)        {            scanf("%d",&a);            int x=query(a,1);            if(x!=0)                update(x,x+a-1,1,1);            printf("%d\n",x);        }        else        {            scanf("%d%d",&a,&b);            update(a,a+b-1,0,1);        }    }    return 0;}