hdu4553

也是一道求连续区间的题,只不过多了优先级,所以要考虑的东西就多了一点点,但核心还是不变的


#include <iostream>
#include <cstdio>
 
using namespace std;
const int maxn = 100000 +5;
 
int n, q;
int s[maxn*4][2], e[maxn*4][2];
int preLen[maxn*4][2], sufLen[maxn*4][2], maxLen[maxn*4][2];
int cover[maxn*4][2];
 
void build(int t, int o, int l, int r)
{
    s[o][t] = l;
    e[o][t] = r;
    preLen[o][t] = maxLen[o][t] = sufLen[o][t] = r - l + 1;
    cover[o][t] = -1;
    int m = (l + r) >> 1;
 
    if(l == r)  return;
    build(t, o << 1, l, m);
    build(t, o << 1 | 1, m+1, r);
}
 
void push_down(int t, int o, int num)
{
    int lc = o << 1;
    int rc = o << 1 | 1;
 
    if(cover[o][t] != -1){
        if(cover[o][t] == 0){
            preLen[lc][t] = maxLen[lc][t] = sufLen[lc][t] = 0;
            preLen[rc][t] = maxLen[rc][t] = sufLen[rc][t] = 0;
            cover[lc][t] = cover[rc][t] = 0;
            cover[o][t] = -1;
        }
        else{
            preLen[lc][t] = maxLen[lc][t] = sufLen[lc][t] = num - (num >> 1);
            preLen[rc][t] = maxLen[rc][t] = sufLen[rc][t] = num >> 1;
            cover[lc][t] = cover[rc][t] = 1;
            cover[o][t] = -1;
        }
    }
}
 
void push_up(int t, int o, int num)
{
    int lc = o << 1, rc = o << 1 | 1;
    preLen[o][t] = preLen[lc][t];
    sufLen[o][t] = sufLen[rc][t];
 
    if(preLen[lc][t] == num - (num >> 1))   preLen[o][t] += preLen[rc][t];
    if(sufLen[rc][t] == num >> 1)   sufLen[o][t] += sufLen[lc][t];
 
    maxLen[o][t] = max(maxLen[lc][t], maxLen[rc][t]);
    maxLen[o][t] = max(maxLen[o][t], sufLen[lc][t] + preLen[rc][t]);
}
 
void update(int t, int l, int r, int c, int o)
{
    if(s[o][t] == l && e[o][t] == r){
        cover[o][t] = c;
        if(c)   preLen[o][t] = maxLen[o][t] = sufLen[o][t] = r - l + 1;
        else    preLen[o][t] = maxLen[o][t] = sufLen[o][t] = 0;
        return;
    }
    if(s[o][t] == e[o][t])  return;
 
    push_down(t, o, e[o][t] - s[o][t] + 1);
    int m = (s[o][t] + e[o][t]) >> 1;
    if(r <= m)  update(t, l, r, c, o << 1);
    else if(l > m)  update(t, l, r, c, o << 1 | 1);
    else{
        update(t, l, m, c, o << 1);
        update(t, m + 1, r, c, o << 1 | 1);
    }
    push_up(t, o, e[o][t] - s[o][t] + 1);
}
 
int query(int t, int len, int o, int l, int r)
{
    if(l == r)  return l;
    push_down(t, o, e[o][t] - s[o][t] + 1);
 
    int m = (s[o][t] + e[o][t]) >> 1;
    int lc = o << 1, rc = o << 1 | 1;
 
    if(maxLen[lc][t] >= len)    return query(t, len, lc, 1, m);
    else if(sufLen[lc][t] + preLen[rc][t] >= len)   return m - sufLen[lc][t] + 1;
    else    return query(t, len, rc, m + 1, r);
}
 
int main()
{
    //freopen("in.txt", "r", stdin);
    int T, kase = 0;
    scanf("%d", &T);
    while(T--){
        scanf("%d%d", &n, &q);
        build(0, 1, 1, n);  //ds
        build(1, 1, 1, n);  //ns
 
        char op[10];
        int x, y;
        printf("Case %d:\n", ++kase);
 
        while(q--){
            scanf("%s", op);
            if(op[0] == 'D'){
                scanf("%d", &x);
                if(maxLen[1][0] >= x){
                    int ans = query(0, x, 1, 1, n);
                    printf("%d,let's fly\n", ans);
                    update(0, ans, ans + x - 1, 0, 1);
                }
                else    printf("fly with yourself\n");
            }
            else if(op[0] == 'N'){
                scanf("%d", &x);
                if(maxLen[1][0] >= x){
                    int ans = query(0, x, 1, 1, n);
                    printf("%d,don't put my gezi\n", ans);
                    update(0, ans, ans + x - 1, 0, 1);
                    update(1, ans, ans + x - 1, 0, 1);
                }
                else{
                    if(maxLen[1][1] >= x){
                        int ans = query(1, x, 1, 1, n);
                        //printf("#:update: %d %d\n", ans, ans + x - 1);
                        printf("%d,don't put my gezi\n", ans);
                        update(0, ans, ans + x - 1, 0, 1);
                        update(1, ans, ans + x - 1, 0, 1);
                    }
                    else printf("wait for me\n");
                }
            }
            else{
                scanf("%d%d", &x, &y);
                printf("I am the hope of chinese chengxuyuan!!\n");
                update(0, x, y, 1, 1);
                update(1, x, y, 1, 1);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38759433/article/details/82530778