HDU - 4614(线段树+二分)

题目:click
题意:操作是1,则从A开始插花F个,多了丢弃,没有瓶子可放则输出。
2的话,区间内的所有花丢出。
用二分去确定操作1中的起始位置以及终止位置,其他的线段树维护。

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 50005*4
using namespace std;
typedef long long ll;
const int MAXN = 262144 * 2+ 10;
const double PI = std::acos(-1.0);
int n,m;
struct A {
    int l,r;
    int w,lazy;
}tree[MAX_len];
void build_tree(int p,int l1,int r1)
{
    tree[p].l=l1,tree[p].r=r1;
    tree[p].lazy=-1;
    tree[p].w=0;
    if(l1==r1)
    {
        return ;
    }
    int mid=(l1+r1)>>1;
    build_tree((p<<1),l1,mid);
    build_tree((p*2+1),mid+1,r1);
    tree[p].w=tree[p*2].w+tree[p*2+1].w;
}
void PushDown(int p)
{//下放标记
    if(tree[p].lazy!=-1)
    {
        int temp=tree[p*2].r-tree[p*2].l+1;
        tree[p*2].w=tree[p].lazy*temp;
        temp=tree[p*2+1].r-tree[p*2+1].l+1;
        tree[p*2+1].w=tree[p].lazy*temp;
        tree[p*2].lazy=tree[p].lazy;
        tree[p*2+1].lazy=tree[p].lazy;
        tree[p].lazy=-1;
    }
}
void update(int p,int l1,int r1,int val)
{
    if(tree[p].l>=l1&&tree[p].r<=r1)
    {
        tree[p].w=val*(tree[p].r-tree[p].l+1);
        tree[p].lazy=val;
        return ;
    }
    PushDown(p);
    int mid=(tree[p].l+tree[p].r)/2;
    if(l1<=mid)
    {
        update(p*2,l1,r1,val);
    }
    if(r1>mid)
    {
        update(p*2+1,l1,r1,val);
    }
    tree[p].w=tree[p*2].w+tree[p*2+1].w;
}
int query(int p,int l1,int r1)
{
    if(l1<=tree[p].l&&r1>=tree[p].r)
    {
        return tree[p].w;
    }
    PushDown(p);
    int mid=(tree[p].l+tree[p].r)/2;
    int res=0;
    if(l1<=mid)
    {
        res+=query(p*2,l1,r1);
    }
    if(r1>mid)
    {
        res+=query(p*2+1,l1,r1);
    }
    return res;
}
int solve(int x,int cnt)
{
    int l=x,r=n;
    int mid=0,ans=0;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(mid-x+1-query(1,x,mid)>=cnt)
        {
            ans=mid;
            r=mid-1;
        }
        else
            l=mid+1;
    }
    return ans;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int i,j;
        scanf("%d %d",&n,&m);
        build_tree(1,1,n);
        while(m--)
        {
            int op;
            scanf("%d",&op);
            if(op==1)
            {
                int x,y;
                scanf("%d %d",&x,&y);
                x++;
                int num=n-x+1-query(1,x,n);
                if(num==0)
                {
                    printf("Can not put any one.\n");
                    continue;
                }
                else
                {
                    int L=solve(x,1);
                    int R=solve(x,min(num,y));
                    update(1,L,R,1);
                    printf("%d %d\n",L-1,R-1);
                }
            }
            else
            {
                int x,y;
                scanf("%d %d",&x,&y);
                x++,y++;
                int num=query(1,x,y);
                update(1,x,y,0);
                printf("%d\n",num);
            }
        }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43958964/article/details/106195184
今日推荐