HDU - 4614 Vases and Flowers 线段树+二分查找

Vases and Flowers

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 5095    Accepted Submission(s): 2109


 

Problem Description

  Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N-1. When she receive some flowers, she will try to put them in the vases, one flower in one vase. She randomly choose the vase A and try to put a flower in the vase. If the there is no flower in the vase, she will put a flower in it, otherwise she skip this vase. And then she will try put in the vase A+1, A+2, ..., N-1, until there is no flower left or she has tried the vase N-1. The left flowers will be discarded. Of course, sometimes she will clean the vases. Because there are too many vases, she randomly choose to clean the vases numbered from A to B(A <= B). The flowers in the cleaned vases will be discarded.

 

 

Input

  The first line contains an integer T, indicating the number of test cases.
  For each test case, the first line contains two integers N(1 < N < 50001) and M(1 < M < 50001). N is the number of vases, and M is the operations of Alice. Each of the next M lines contains three integers. The first integer of one line is K(1 or 2). If K is 1, then two integers A and F follow. It means Alice receive F flowers and try to put a flower in the vase A first. If K is 2, then two integers A and B follow. It means the owner would like to clean the vases numbered from A to B(A <= B).

 

 

Output

  For each operation of which K is 1, output the position of the vase in which Alice put the first flower and last one, separated by a blank. If she can not put any one, then output 'Can not put any one.'. For each operation of which K is 2, output the number of discarded flowers. 
  Output one blank line after each test case.

 

 

Sample Input

 

2 10 5 1 3 5 2 4 5 1 1 8 2 3 6 1 8 8 10 6 1 2 5 2 3 4 1 0 8 2 2 5 1 4 4 1 2 3

 

 

Sample Output

 

[pre]3 7 2 1 9 4 Can not put any one. 2 6 2 0 9 4 4 5 2 3 [/pre]

 

 

Author

SYSU

 

 

Source

2013 Multi-University Training Contest 2

 

 

Recommend

zhuyuanchen520

 

题意:

n个花瓶,开始全空,m次操作,

第一种:1,x,v,就是将从x往后的区间内内花瓶放华,如果有花了就跳掉往后,结束的条件是插到末尾了或者花插没了,输出:插花的开始位置和结束插花的位置,如果一个都不能插,输出“Can not put any one.”;

第二种:如果输入2,输入x,y就是将x,y内的花清空

分析:

对于第二种操作,简单的区间更新就可以做。

对于第一种操作的话,因为给出的x到后面区间内的空瓶的个数不知道,所以,无法直接区间更新,但是单点查询,单点更新,肯定过于复杂,这时候二分就要出现了,我们二分枚举位置y,最小的满足x和y区间内满足有v个空瓶。

注意看一下代码的二分查找的方法

 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
 
#define lson i<<1
#define rson i<<1|1
#define LS l,mid,lson
#define RS mid+1,r,rson
#define LL long long
#define N 50005
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define EXP 1e-8
#define lowbit(x) (x&-x)
 
int ans_sum,ans_max,ans_min;
int n;
int vis[N];
struct node
{
    int l,r;
    int sum;
    int set;
} a[N<<2];
 
void pushdown(int i)//标记下传
{
        if(a[i].set!=-1)
    {
        a[lson].set = a[rson].set = a[i].set;
        a[lson].sum = (a[lson].r-a[lson].l+1)*a[i].set;
        a[rson].sum = (a[rson].r-a[rson].l+1)*a[i].set;
        
        a[i].set = -1;
    }
}
 
void pushup(int i)
{
    a[i].sum=a[lson].sum+a[rson].sum;
}
//建立线段树 
void build(int l,int r,int i)
{
    a[i].l = l;
    a[i].r = r;
    a[i].set = -1;
    if(l == r)     
	{
	a[i].sum =1;
	return;
	}
    int mid = (l+r)>>1;
    build(LS);
    build(RS);
    pushup(i);
} 
//a[l,r]都变为val
void update(int l,int r,int i,int val) 
{
    if(a[i].l>=l&&a[i].r<=r)
    {
    	if(a[i].l==a[i].r)
    	vis[l]=0;
        a[i].sum = val*(a[i].r-a[i].l+1);
        a[i].set = val;
        return;
    }
    pushdown(i);         //标记下传
    int mid = (a[i].l+a[i].r)>>1;
    if(l<=mid) update(l,r,lson,val);
    if(r>mid) update(l,r,rson,val);
    pushup(i);
}

 
void query(int l,int r,int i)
{
    if(l <= a[i].l && a[i].r <= r)
    {
        ans_sum += a[i].sum;
        return ;
    }
    pushdown(i);
    int mid = (a[i].l+a[i].r)>>1;
    if(l<=mid) query(l,r,lson);
    if(r>mid) query(l,r,rson);
    pushup(i);
}

int find_(int x,int f)
{
	int l=x,r=n;
    //cout<>1;
		ans_sum=0;
		query(x,mid,1);
		//cout<=f)
		 {
		 	 r=mid;
		 }   
		else
			l=mid+1;
	}
	//cout<

 

你可能感兴趣的:(算法基础--二分,数据结构--线段树,好题,比赛题解)