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

题目链接

思路:线段树维护区间和,当k=1时,询问二分询问[x-(x~n-1)]找到最小位置,复杂度n*logn*logn卡过

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<stack>
#include<vector>
#include<map>
#include<queue>
#define myself i,l,r
#define lson i<<1
#define rson i<<1|1
#define Lson i<<1,l,mid
#define Rson i<<1|1,mid+1,r
#define half (l+r)/2
#define inff 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define PI 3.14159265358979323846
#define min4(a,b,c,d) min(min(a,b),min(c,d))
#define min3(x,y,z) min(min(x,y),min(y,z))
#define pii make_pair
#define pr pair<int,int>
const int dir[4][2]= {0,-1,-1,0,0,1,1,0};
typedef long long ll;
const ll inFF=9223372036854775807;
typedef unsigned long long ull;
using namespace std;
const int maxn=5e4+5;
int n,m;
int tree[maxn<<2],lazy[maxn<<2];
void pushup(int i)
{
    tree[i]=tree[lson]+tree[rson];
}
void pushdown(int i,int l,int r)
{
    int mid=half;
    if(lazy[i]!=-1)
    {
        tree[lson]=(mid-l+1)*lazy[i];
        tree[rson]=(r-mid)*lazy[i];
        lazy[lson]=lazy[rson]=lazy[i];
        lazy[i]=-1;
    }
}
void build(int i,int l,int r)
{
    lazy[i]=-1;
    tree[i]=1;
    if(l==r) return ;
    int mid=half;
    build(Lson);
    build(Rson);
    pushup(i);
}
int query(int i,int l,int r,int ql,int qr)
{
    if(ql<=l&&qr>=r) return tree[i];
    int mid=half;
    pushdown(i,l,r);
    if(qr<=mid) return query(Lson,ql,qr);
    else if(ql>=mid+1) return query(Rson,ql,qr);
    else return query(Lson,ql,mid)+query(Rson,mid+1,qr);
}
void update(int i,int l,int r,int ql,int qr,int val)
{
    if(ql<=l&&qr>=r)
    {
        tree[i]=val*(r-l+1);
        lazy[i]=val;
        return;
    }
    pushdown(i,l,r);
    int mid=half;
    if(qr<=mid) update(Lson,ql,qr,val);
    else if(ql>=mid+1) update(Rson,ql,qr,val);
    else update(Lson,ql,mid,val),update(Rson,mid+1,qr,val);
    pushup(i);
}
int erfen(int x,int r,int val)
{
    int l=x,mid,ans;
    while(l<=r)
    {
        mid=half;
        if(query(1,0,n-1,x,mid)>=val){
            ans=mid;
            r=mid-1;
        }
        else
            l=mid+1;
    }
    return ans;
}
int main()
{
    int t,op,x,y,val;
    cin>>t;
    while(t--)
    {
        scanf("%d %d",&n,&m);
        build(1,0,n-1);
        while(m--)
        {
            scanf("%d %d %d",&op,&x,&y);
            if(op==2)
            {
                val=query(1,0,n-1,x,y);
                printf("%d\n",y-x+1-val);
                update(1,0,n-1,x,y,1);
            }
            else
            {
                val=query(1,0,n-1,x,n-1);
                if(val==0) printf("Can not put any one.\n");
                else
                {
                    int l=x,r=n-1,s,e;
                    s=erfen(x,n-1,1);
                    if(val<=y)
                        e=erfen(x,n-1,val);
                    else
                        e=erfen(x,n-1,y);
                    printf("%d %d\n",s,e);
                    update(1,0,n-1,x,e,0);
                }
            }
        }
        printf("\n");
    }
}

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值