昨天学习了线段树的延迟标记;
发现自己还有区间合并没有学;
抓紧时间学习一下;
代码:
#include<cstdio>
#include<algorithm>
#define maxn 200005
using namespace std; struct tree
{
int l,r,msum,lsum,rsum,flag;
tree *right,*left;
}tr[maxn];
int nonocount; void build(tree *root,int l,int r)
{
root->l=l,root->r=r,root->flag=-;
root->msum=root->lsum=root->rsum=r-l+;
if(l==r)return;
int mid=(l+r)>>;
nonocount++;
root->left=tr+nonocount;
nonocount++;
root->right=tr+nonocount;
build(root->left,l,mid);
build(root->right,mid+,r);
} void pushdown(tree *root,int mid)
{
if(root->flag!=-)
{
root->left->flag=root->right->flag=root->flag;
int x=root->flag?:mid-(mid>>);
root->left->lsum=root->left->msum=root->left->rsum=x;
int y=root->flag?:(mid>>);
root->right->lsum=root->right->msum=root->right->rsum=y;
root->flag=-;
}
} void pushup(tree *root,int mid)
{
root->lsum=root->left->lsum;
root->rsum=root->right->rsum;
if(root->lsum==mid-(mid>>))root->lsum+=root->right->lsum;
if(root->rsum==(mid>>))root->rsum+=root->left->rsum;
root->msum=max(root->right->lsum+root->left->rsum,max(root->left->msum,root->right->msum));
} void update(tree *root,int l,int r,int c)
{
int x=root->r-root->l+;
if(l<=root->l&&root->r<=r)
{
root->msum=root->lsum=root->rsum=c?:x;
root->flag=c;
return;
}
pushdown(root,x);
int mid=(root->l+root->r)>>;
if(l<=mid)update(root->left,l,r,c);
if(r>mid) update(root->right,l,r,c);
pushup(root,x);
} int query(tree *root,int w)
{
int x=root->r-root->l+;
if(root->l==root->r)return root->l;
pushdown(root,x);
int mid=(root->l+root->r)>>;
if(root->left->msum>=w)return query(root->left,w);
else if(root->left->rsum+root->right->lsum>=w)return mid-root->left->rsum+;
return query(root->right,w);
}
int n,m,a,b,c;
int main()
{
scanf("%d%d",&n,&m);
build(tr,,n);
while(m--)
{
scanf("%d",&a);
if(a==)
{
scanf("%d",&b);
if(tr->msum<b)puts("");
else
{
int p=query(tr,b);
printf("%d\n",p);
update(tr,p,p+b-,);
}
}
else
{
scanf("%d%d",&b,&c);
update(tr,b,b+c-,);
}
}
return ;
}