版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
先呈上原题链接[HDU-4614]
题意:
有n个花瓶,每个花瓶中只能放一朵花。
两种操作:
第一种是从A开始放F朵花,如果有的花瓶中已经有花则跳过这个花瓶,往下一个花瓶放;
第二种是将区间[A,B]之间花瓶中的花清空。
如果是第一种操作,输出这次放的花的左右端点;如果是第二种操作,输出这次总共清理出了多少支花。
思路:
很裸的线段树的题啦。
用线段树维护区间花瓶空位。
第一种操作,两次二分分别寻找插花的起始位置和终止位置,再区间更新。
第二种操作直接区间更新就行了。
坑点:
其实也不算坑点啦,只是要注意下第一种操作的输入不一定其实位置能插花(我当时就是因为这个。。。算了,都怪我傻)。
good luck and have fun!!!
附上代码:
#include<bits/stdc++.h>
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define test(flag,value) cout<<flag<<":"<<(value)<<endl
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int INF=0x3f3f3f3f;
const int MAXN=1e5+5;
const int MOD=1e9+7;
const double PI=acos(-1);
int sum[MAXN<<2],lazy[MAXN<<2];
int n,m;
inline void push_up(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void push_down(int rt,int l,int r)
{
if(lazy[rt]==-1) return;
int m=(l+r)>>1;
lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
sum[rt<<1]=(m-l+1)*lazy[rt];
sum[rt<<1|1]=(r-m)*lazy[rt];
lazy[rt]=-1;
}
void build(int l,int r,int rt)
{
if(l==r)
{
sum[rt]=1;
return;
}
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
push_up(rt);
}
void update(int L,int R,int l,int r,int rt,int val)
{
if(L<=l&&r<=R)
{
sum[rt]=val*(r-l+1);
lazy[rt]=val;
return;
}
push_down(rt,l,r);
int m=(l+r)>>1;
if(L<=m) update(L,R,l,m,rt<<1,val);
if(R>m) update(L,R,m+1,r,rt<<1|1,val);
push_up(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
return sum[rt];
push_down(rt,l,r);
int m=(l+r)>>1;
int ret=0;
if(L<=m) ret+=query(L,R,l,m,rt<<1);
if(R>m) ret+=query(L,R,m+1,r,rt<<1|1);
return ret;
}
int bin(int st,int num)
{
int l=st;
int r=n;
while(l<=r)
{
int m=(l+r)>>1;
int cnt=query(st,m,1,n,1);
if(cnt>num||(cnt==num&&query(m,m,1,n,1)==0))
r=m;
else if(cnt<num)
l=m+1;
else
{
return m;
}
}
}
int main(void)
{
int _;scanf("%d",&_);
while(_--)
{
scanf("%d%d",&n,&m);
build(1,n,1);
mem(lazy,-1);
while(m--)
{
int k;
scanf("%d",&k);
if(k==1)
{
int f,a;
scanf("%d%d",&a,&f);
a++;
int num=query(a,n,1,n,1);
if(num==0)
printf("Can not put any one.\n");
else
{
int spos=bin(a,1);
if(num<f)f=num;
int epos=bin(spos,f);
update(spos,epos,1,n,1,0);
printf("%d %d\n", spos-1,epos-1);
}
}
else if(k==2)
{
int l,r;
scanf("%d%d",&l,&r);
l++;r++;
int ans=(r-l+1)-query(l,r,1,n,1);
printf("%d\n", ans);
update(l,r,1,n,1,1);
}
}
printf("\n");
}
}