HDU 4614 Vases and Flowers 線段樹區間更新

題意:給你n個花瓶,m次操作,若k==1,則從第A個開始插入花,直到插入了F朵花或者沒有空花瓶了,若k==2,則將花瓶a~b清空。

思路:比較裸的線段樹,對於第一種操作,若能插花則先求出插花的左右邊界,然後將這個區間空位更新爲0,第二種操作,詢問區間花瓶數後直接將此區間空位更新爲區間的r-l+1.

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef __int64 int64;
typedef long long ll;
#define M 50005
#define N 1000005
#define max_inf 0x7f7f7f7f
#define min_inf 0x80808080
#define mod 1000000007

struct node
{
	int l , r , sum , fg;
}tree[4*M];
int n , m;

void Build(int rt , int l  ,int r)
{
	tree[rt].l = l;
	tree[rt].r = r;
	tree[rt].sum = r-l+1;
	tree[rt].fg = -1;
	if (l == r)return;
	int mid = (l+r)>>1;
	Build(rt<<1,l,mid);
	Build(rt<<1|1,mid+1,r);
}

void Updata_down(int rt)
{
	if (tree[rt].fg != -1)
	{
		tree[rt<<1].fg = tree[rt<<1|1].fg = tree[rt].fg;
		tree[rt<<1].sum = tree[rt].fg*(tree[rt<<1].r-tree[rt<<1].l+1);
		tree[rt<<1|1].sum = tree[rt].fg*(tree[rt<<1|1].r-tree[rt<<1|1].l+1);
		tree[rt].fg = -1;
	}
}

int Query(int rt , int l , int r)
{
	if (tree[rt].l == l && tree[rt].r == r)return tree[rt].sum; 
	Updata_down(rt);
	int mid = (tree[rt].l+tree[rt].r)>>1;
	if (l > mid)return Query(rt<<1|1,l,r);
	if (r <= mid)return Query(rt<<1,l,r);
	return Query(rt<<1,l,mid)+Query(rt<<1|1,mid+1,r);
}

int Find(int rt , int l , int r , int pos)
{
	if (tree[rt].l == tree[rt].r)return tree[rt].l;
	int mid = (tree[rt].l+tree[rt].r)>>1;
	if (r <= mid)return Find(rt<<1,l,r,pos);
	if (l > mid)return Find(rt<<1|1,l,r,pos);
	int sum = Query(rt,l,mid);
	if (pos <= sum)return Find(rt<<1,l,mid,pos);
	return Find(rt<<1|1,mid+1,r,pos-sum);
}

void Updata(int rt , int l , int r , int val)
{
	if (tree[rt].l == l && r == tree[rt].r)
	{
		tree[rt].fg = val;
		tree[rt].sum = val*(r-l+1);
		return;
	}
	Updata_down(rt);
	int mid = (tree[rt].l+tree[rt].r)>>1;
	if (r <= mid)Updata(rt<<1,l,r,val);
	else if (l > mid)Updata(rt<<1|1,l,r,val);
	else
	{
		Updata(rt<<1,l,mid,val);
		Updata(rt<<1|1,mid+1,r,val);
	}
	tree[rt].sum = tree[rt<<1].sum+tree[rt<<1|1].sum;
}

int main()
{
	int t;
	scanf("%d",&t);
	while (t--)
	{
		scanf("%d%d",&n,&m);
		Build(1 , 0 , n-1);
		while (m--)
		{
			int k , a ,  b;
			scanf("%d%d%d",&k,&a,&b);
			if (k == 1)
			{
				int s = Query(1,a,n-1);
				if (s == 0)printf("Can not put any one.\n");
				else
				{
					s = min(s,b);
					int za = Find(1,a,n-1,1);
					int yb = Find(1,a,n-1,s);
					printf("%d %d\n",za,yb);
					Updata(1,za,yb,0);
				}
			}
			else
			{
				printf("%d\n",b-a+1-Query(1,a,b));
				Updata(1,a,b,1);
			}
		}
		printf("\n");
	}
	return 0;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章