hdu 4614 Vases and Flowers

这个题目其实不用二分应该能快点,感觉应该会写很多函数,很多种情况。

所以选择二分+线段树来实现起来简单点。

思路还算是比较简单的。

#include <iostream>
#include <cstdio>
#include <set>

using namespace std;
const int maxn = 100010;
int num[maxn<<2],mask[maxn<<2],ansl,ansr;

void pushdown(int l,int r,int rt)
{
    if (mask[rt] == 1)
    {
        mask[rt<<1] = 1;
        mask[rt<<1|1] = 1;
        int m = (l+r)>>1;
        num[rt<<1] = m-l+1;
        num[rt<<1|1] = r-m;
        mask[rt] = -1;
        //cout << "bug" << endl;
    } else if (mask[rt] == 0) {
        mask[rt<<1] = 0;
        mask[rt<<1|1] = 0;

        num[rt<<1] = 0;
        num[rt<<1|1] = 0;
        mask[rt] = -1;
    }
}

void pushup(int rt)
{
    num[rt] = num[rt<<1] + num[rt<<1|1];
}

int query(int L,int R,int type,int l,int r,int rt)
{
    if (L > R) return 0;
    if (L <= l && R >= r) {
        if (type == -1) return num[rt];
        if (type == 1) {
            int result = r - l + 1 - num[rt];
            num[rt] = r - l + 1;
            mask[rt] = 1;
            return result;
        }
        int result = num[rt];
        num[rt] = 0;
        mask[rt] = 0;
        return result;
    }
    int m = (l + r)>>1;
    pushdown(l,r,rt);
    int ret = 0;
    if (L <= m) ret += query(L,R,type,l,m,rt<<1);
    if (R > m)  ret += query(L,R,type,m+1,r,rt<<1|1);
    pushup(rt);
    return ret;
}
int binary_find(int cnt,int n)
{
    int l = 0 ,r = n - 1,ret = 0;
    while(l <= r)
    {
        int m = (l+r)>>1;
        int number = query(0,m,-1,0,n-1,1);
        if (number >= cnt) {
            ret = m;
            r = m - 1;
        } else l = m + 1;
    }
    return ret;
}
void solve(int start,int cnt,int n)
{
    int pre = query(0,start-1,-1,0,n-1,1);
    int behind = query(start,n-1,-1,0,n-1,1);
    //cout << pre << "  " << behind << endl;
    cnt = min(cnt,behind);
    if (cnt == 0) return;
    ansl = binary_find(pre+1,n);
    ansr = binary_find(pre + cnt,n);
    query(ansl,ansr,0,0,n-1,1);
}
int main()
{
    int T,n,m,K,A,B;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d",&n,&m);
        //线段树初始化
        num[1] = n;
        mask[1] = 1;

        while(m--)
        {
            scanf("%d %d %d",&K,&A,&B);
            if (K == 1) {
               ansl = ansr = -1;
               solve(A,B,n);
               if (ansl != -1) printf("%d %d\n",ansl,ansr);
               else puts("Can not put any one.");
            } else {
                printf("%d\n",query(A,B,1,0,n-1,1));
            }
        }
        puts("");
    }
    return 0;
}


你可能感兴趣的:(hdu 4614 Vases and Flowers)