hdu 1540 Tunnel Warfare

iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。

iterator upper_bound( const key_type &key ):返回一个迭代器,指向键值> key的第一个元素。

用stl和线段树都写了一遍。难的地方在于寻找pos所在位置的连续块的长度。

/*
Pro: 0

Sol:

date:2012/09/24 19:14-
*/
//#include <iostream>
//#include <cstdio>
//#include <algorithm>
//#include <cstring>
//#include <cmath>
//#include <queue>
//#include <set>
//#include <vector>
//using namespace std;
//char op[10];
//int cnt ,m,n,x;
//set <int> mp;
//int stack[51000];
//int main(){
//    while(scanf("%d%d",&n,&m) != EOF){
//        mp.clear();
//        mp.insert(0);
//        mp.insert(n + 1);
//        cnt = 0;
//        for(int i = 0;  i < m; i++){
//            scanf("%s",op);
//            if(op[0] != 'R') scanf("%d",&x);
//            if(op[0] == 'D'){
//                stack[cnt ++] = x;
//                mp.insert(x);
//            }else if(op[0] == 'Q'){
//                if(*mp.lower_bound(x) == x)
//                    printf("0\n");
//                else{
//                    set <int> :: iterator it;
//                    it = mp.lower_bound(x);
//                    printf("%d\n", *it - *(--it) - 1);
//                }
//            }else if(op[0] == 'R'){
//                mp.erase(mp.find(stack[--cnt]));
//            }
//        }
//    }
//	return 0;
//}
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
#define maxn 50010
#define havem int m = (l + r) >> 1
#define lson l,m , rt << 1
#define rson m+ 1, r, rt << 1|1
#define ls rt << 1
#define rs rt << 1|1
using namespace std;
char op[10];
int cnt ,m,n,x,li,ri;
int stack[51000];
int lsum[maxn << 2], rsum[maxn << 2], msum[maxn << 2];
void build(int l,int r, int rt){
    lsum[rt] = rsum[rt] = msum[rt] = r -l + 1;
    if(l ==r) return ;
    havem;
    build(lson); build(rson);
}
void up(int rt, int m){
    lsum[rt] = (lsum[ls] == m - (m >> 1)) ? lsum[ls] + lsum[rs] : lsum[ls];
    rsum[rt] = (rsum[rs] == (m >> 1)) ? rsum[ls] + rsum[rs] : rsum[rs];
    msum[rt] = max( max(msum[ls], msum[rs]), rsum[ls] + lsum[rs] );
}
void update(int pos, int val, int l, int r, int rt){
    if(l == r){
        lsum[rt] = rsum[rt] = msum[rt] = val;
        return ;
    }havem;
    if(pos <= m) update(pos,val,lson);
    else update(pos,val,rson);
    up(rt, r - l + 1);
}
int query(int pos,int l, int r, int rt){//寻找pos所在位置的连续1的长度
    if(msum[rt] == 0) return 0;
    if(msum[rt] == r - l + 1) return msum[rt];
havem;//这个不要忘了。就因为这个调了10分钟。敲只敲了3分钟,当然是照着敲的
    if(lsum[rt] && lsum[rt] + l - 1 >= pos) return lsum[rt];//左边
    if(rsum[rt] && r - rsum[rt] + 1 <= pos) return rsum[rt];//右边
    //中间的情况还要分批考虑,这是之前不会写的地方。导致下面的pos<= m都不会写了。
    if(pos <= m && m - rsum[ls] + 1 <= pos && rsum[ls]) return lsum[rs] + rsum[ls];
    if(pos > m && m + lsum[rs] >= pos && lsum[rs])  return lsum[rs] + rsum[ls];

    if(pos <= m)
        return query(pos,lson);
    else
        return query(pos,rson);
}
int main(){
    while(scanf("%d%d",&n,&m) != EOF){
        build(1,n,1); cnt = 0;
        for(int i = 0;  i < m; i++){
            scanf("%s",op);
            if(op[0] != 'R') scanf("%d",&x);
            if(op[0] == 'D'){
                update(x,0,1,n,1);
                stack[cnt ++] = x;
            }else if(op[0] == 'Q'){
                int ans = query(x,1,n,1);
                printf("%d\n",ans);
            }else if(op[0] == 'R'){
                update(stack[-- cnt], 1, 1,n,1);
            }
        }
    }
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值