poj2892

跟poj3667差不多

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 50005;

struct Tree{
    int l, r;
    int l_len, r_len;
    int t_len;
};
Tree tree[MAXN << 2];
int record[MAXN];
int N, M;

void construct(int l, int r, int k) {
    tree[k].l = l;
    tree[k].r = r;
    tree[k].l_len = tree[k].r_len = tree[k].t_len = r - l + 1;
    if(l == r) {
        return;
    }
    int mid = l + r >> 1;
    construct(l, mid, k << 1);
    construct(mid + 1, r, k << 1 | 1);
}

void update(int x, int action, int k) {
    if(tree[k].l == tree[k].r) {
        tree[k].t_len = tree[k].l_len = tree[k].r_len = action;
        return;
    }
    int mid = tree[k].l + tree[k].r >> 1;
    if(x <= mid) {
        update(x, action, k << 1);
    } else {
        update(x, action, k << 1 | 1);
    }
    tree[k].t_len = max(tree[k << 1].r_len + tree[k << 1 | 1].l_len, max(tree[k << 1].t_len, tree[k << 1 | 1].t_len));
    tree[k].l_len = tree[k << 1].l_len == mid - tree[k].l + 1 ? tree[k << 1].l_len + tree[k << 1 | 1].l_len : tree[k << 1].l_len;
    tree[k].r_len = tree[k << 1 | 1].r_len == tree[k].r - mid ? tree[k << 1 | 1].r_len + tree[k << 1].r_len : tree[k << 1 | 1].r_len;
}

int query(int x, int k) {
    if(tree[k].l == tree[k].r || tree[k].t_len == 0 || tree[k].t_len == tree[k].r - tree[k].l + 1) {
        return tree[k].t_len;
    }
    int mid = tree[k].l + tree[k].r >> 1;
    if(x <= mid) {
        if(x >= mid - tree[k << 1].r_len + 1) {
            return tree[k << 1].r_len + tree[k << 1 | 1].l_len;
        } else {
            return query(x, k << 1);
        }
    } else {
        if(x <= tree[k << 1 | 1].l_len + mid) {
            return tree[k << 1].r_len + tree[k << 1 | 1].l_len;
        } else {
            return query(x, k << 1 | 1);
        }
    }
}

int main() {
    freopen("poj2892.txt", "r", stdin);
    char str[4];
    int x, cnt;
    while(scanf("%d%d", &N, &M) != EOF) {
        cnt = 0;
        construct(1, N, 1);
        while(M --) {
            scanf("%s", str);
            if(str[0] == 'D') {
                scanf("%d", &x);
                record[cnt ++] = x;
                update(x, 0, 1);
            }
            if(str[0] == 'R') {
                cnt --;
                if(cnt >= 0) {
                    x = record[cnt];
                    update(x, 1, 1);
                }
            }
            if(str[0] == 'Q') {
                scanf("%d", &x);
                printf("%d\n", query(x, 1));
            }
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值