hdu 4614 线段树

时间:2023-03-09 03:10:07
hdu 4614 线段树

思路:当k为1的时候,用二分法查询包含有f个空瓶的上界r,然后更新会方便很多,直接更新区间(a,r)了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define lson(x) (x<<1)
#define rson(x) ((x<<1)+1)
#define mid ((tree[po].l+tree[po].r)>>1)
#define inf 1<<30
#define Maxm 1000000
#define Maxn 60000
using namespace std;
struct Tree{
int l,r,left,up;
}tree[Maxm];
int flag=,ans,fir;
void buildTree(int l,int r,int po)
{
tree[po].l=l,tree[po].r=r;
tree[po].left=r-l+;
tree[po].up=;
if(l==r)
return ;
buildTree(l,mid,lson(po));
buildTree(mid+,r,rson(po));
}
void down(int po)
{ if(!tree[po].left)
{
tree[po].up=;
tree[lson(po)].left=;
tree[rson(po)].left=;
tree[rson(po)].up=;
tree[lson(po)].up=;
return ;
}
if(!tree[po].up) return ;
tree[lson(po)].left=mid-tree[po].l+;
tree[rson(po)].left=tree[po].r-mid;
tree[rson(po)].up=;
tree[lson(po)].up=;
tree[po].up=;
}
void update(int l,int r,int po)
{
if(l<=tree[po].l&&r>=tree[po].r)
{
ans+=tree[po].r-tree[po].l+-tree[po].left;
tree[po].left=tree[po].r-tree[po].l+;
tree[po].up=;
return ;
}
down(po);
if(r<=mid)
update(l,r,lson(po));
else
if(l>mid)
update(l,r,rson(po));
else{
update(l,r,lson(po));
update(l,r,rson(po));
}
tree[po].left=tree[lson(po)].left+tree[rson(po)].left;
}
int findTree(int l,int r,int po)
{
if(l<=tree[po].l&&r>=tree[po].r)
{
return tree[po].left;
}
down(po);
int temp=;
if(r<=mid)
temp=findTree(l,r,lson(po));
else
if(l>mid)
temp=findTree(l,r,rson(po));
else{
temp=findTree(l,r,lson(po));
temp+=findTree(l,r,rson(po));
}
tree[po].left=tree[lson(po)].left+tree[rson(po)].left;
return temp;
}
void Insert(int l,int r,int po)
{
if(l<=tree[po].l&&r>=tree[po].r)
{
if(tree[po].left==tree[po].r-tree[po].l+&&!flag)
flag=,fir=tree[po].l;
if(flag)
{
tree[po].left=;
return ;
}
}
if(!tree[po].left)
return ;
down(po);
if(r<=mid)
Insert(l,r,lson(po));
else
if(l>mid)
Insert(l,r,rson(po));
else{
Insert(l,r,lson(po));
Insert(l,r,rson(po));
}
tree[po].left=tree[lson(po)].left+tree[rson(po)].left;
}
int main()
{
int n,m,k,a,b,i,j,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
buildTree(,n-,);
for(i=;i<=m;i++)
{
scanf("%d%d%d",&k,&a,&b);
if(k==)
{
flag=;
int l,r,Mid,temp;
temp=findTree(a,n-,);
if(temp<b)
b=temp;
l=a,r=n-;
while(r>l)
{
Mid=(l+r)>>;
temp=findTree(a,Mid,);
if(temp>=b)
r=Mid;
else
l=Mid+;
}
Insert(a,r,);
if(!flag)
printf("Can not put any one.\n");
else
printf("%d %d\n",fir,r);
}
else
{
ans=;
update(a,b,);
printf("%d\n",ans);
}
}
printf("\n");
}
return ;
}