hdu4614

hdu4614 Vases and Flowers
传送门
题意
\(n(2\leq n\leq 50000)\)个花瓶,初始为空,有2种操作:
1.从花瓶\(a\)开始向后,在空的花瓶中插入一朵花,最多插入\(b\)朵花,判断是否可以插入至少一朵花,如果可以,计算第一个插花的花瓶编号和最后一个插花的花瓶编号
2.将\([a,b]\)内的花清空,计算清空的花朵数量
题解
线段树维护区间内空花瓶的数量
对于操作1,首先判断\([a,n]\)区间内的空花瓶数量是否为零,如果不为零,二分查找左端点,再二分查找右端点
对于操作2,直接查询\([a,b]\)区间内的空花瓶数量,区间长度减去空花瓶数量为花朵数量

#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<string>
#include<sstream>
#include<cmath>
#include<ctime>
#include<climits>
#include<algorithm>
#define LL long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define PLI pair<LL,int>
#define pi acos(-1.0)
#define eps 1e-6
#define lowbit(x) x&(-x)
using namespace std;

const int maxn=50010;
int T,n,m,tree[4*maxn],lazy[4*maxn];

void pushup(int o){
	tree[o]=tree[o<<1]+tree[o<<1|1];
}

void build(int o,int l,int r){
	lazy[o]=-1;
	if(l==r){
		tree[o]=1;
		return;
	}
	int mid=(l+r)>>1;
	build(o<<1,l,mid);
	build(o<<1|1,mid+1,r);
	pushup(o);
}

void puttag(int o,int l,int r,int v){
	lazy[o]=v;
	tree[o]=v*(r-l+1);
}

void pushdown(int o,int l,int r){
	if(lazy[o]==-1) return;
	lazy[o<<1]=lazy[o];
	lazy[o<<1|1]=lazy[o];
	int mid=(l+r)>>1;
	tree[o<<1]=lazy[o]*(mid-l+1);
	tree[o<<1|1]=lazy[o]*(r-mid);
	lazy[o]=-1;
}

void change(int o,int l,int r,int ql,int qr,int v){
	if(ql<=l && r<=qr){
		puttag(o,l,r,v);
		return;
	}
	int mid=(l+r)>>1;
	pushdown(o,l,r);
	if(ql<=mid) change(o<<1,l,mid,ql,qr,v);
	if(qr>mid) change(o<<1|1,mid+1,r,ql,qr,v);
	pushup(o);
}

int query(int o,int l,int r,int ql,int qr){
	if(ql<=l && r<=qr) return tree[o];
	int mid=(l+r)>>1;
	pushdown(o,l,r);
	int ans=0;
	if(ql<=mid) ans+=query(o<<1,l,mid,ql,qr);
	if(qr>mid) ans+=query(o<<1|1,mid+1,r,ql,qr);
	return ans;
}

int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d %d",&n,&m);
		build(1,1,n);
		while(m--){
			int k,a,b;
			scanf("%d %d %d",&k,&a,&b);
			if(k==1){
				a++;
				int sum=query(1,1,n,a,n);
				if(sum==0) printf("Can not put any one.\n");
				else{
					int st,ed;
					int l=a,r=n;
					while(r>l){
						int mid=(l+r)>>1;
						if(query(1,1,n,a,mid)>=1) r=mid;
						else l=mid+1;
					}
					st=r;
					l=st;
					r=n;
					b=min(b,sum);
					while(r>l){
						int mid=(l+r)>>1;
						if(query(1,1,n,st,mid)>=b) r=mid;
						else l=mid+1;
					}
					ed=r;
					printf("%d %d\n",st-1,ed-1);
					change(1,1,n,st,ed,0);
				}
			}
			else{
				a++;
				b++;
				printf("%d\n",b-a+1-query(1,1,n,a,b));
				change(1,1,n,a,b,1);
			}
		}
		printf("\n");
	}
}
posted @ 2020-09-26 14:08  fxq1304  阅读(88)  评论(0编辑  收藏  举报