码迷,mamicode.com
首页 > 其他好文 > 详细

poj2892--Tunnel Warfare(线段树)

时间:2015-07-15 15:12:00      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:点击打开链接

题目大意:给出n个格子,三种操作,D k:消除第k个格子,R:恢复最后一次消除的格子,Q k:问和k相连的最长连续序列。

求最长连续序列,线段树统计每段中被消除的最大点和最小点,更新点k,查询段[1,k][k,n],然后相减得到结果

#include <cstdio>
#include <cstring>
#include <stack>
#include <algorithm>
using namespace std ;
#define INF 0x3f3f3f3f
int cl_max[500000] , cl_min[500000] ;
stack <int> sta ;
void push_up(int rt) {
    cl_max[rt] = max(cl_max[rt<<1],cl_max[rt<<1|1]) ;
    cl_min[rt] = min(cl_min[rt<<1],cl_min[rt<<1|1]) ;
}
void update(int k,int flag,int l,int r,int rt) {
    if(l == r) {
        if( flag == -1 )
            cl_max[rt] = 0 , cl_min[rt] = INF ;
        else
            cl_max[rt] = cl_min[rt] = k ;
        return ;
    }
    if( k <= (l+r)/2 )
        update(k,flag,l,(l+r)/2,rt<<1) ;
    else
        update(k,flag,(l+r)/2+1,r,rt<<1|1) ;
    push_up(rt) ;
}
int query1(int ll,int rr,int l,int r,int rt) {
    if( rr < l || ll > r ) return 0 ;
    if( ll <= l && rr >= r ) return cl_max[rt] ;
    return max(query1(ll,rr,l,(l+r)/2,rt<<1),query1(ll,rr,(l+r)/2+1,r,rt<<1|1)) ;
}
int query2(int ll,int rr,int l,int r,int rt) {
    if( rr < l || ll > r ) return INF ;
    if( ll <= l && rr >= r ) return cl_min[rt] ;
    return min(query2(ll,rr,l,(l+r)/2,rt<<1),query2(ll,rr,(l+r)/2+1,r,rt<<1|1)) ;
}
int main() {
    int n , m , k , min1 , max1 ;
    char s[5] ;
    while( scanf("%d %d", &n, &m) !=EOF ) {
        memset(cl_max,0,sizeof(cl_max)) ;
        memset(cl_min,INF,sizeof(cl_min)) ;
        while( !sta.empty() ) sta.pop() ;
        while( m-- ) {
            scanf("%s", s) ;
            if( s[0] == 'D' ) {
                scanf("%d", &k) ;
                sta.push(k) ;
                update(k,1,1,n,1) ;
            }
            else if( s[0] == 'Q' ) {
                scanf("%d", &k) ;
                max1 = query1(1,k,1,n,1) ;
                min1 = query2(k,n,1,n,1) ;
                //printf("Q--> max1 = %d min1 = %d\n", max1 , min1) ;
                if( min1 == INF ) min1 = n+1 ;
                if( max1 == min1 )
                    printf("0\n") ;
                else
                    printf("%d\n", min1-1-max1 ) ;
            }
            else{
                k = sta.top() ;
                sta.pop() ;
                update(k,-1,1,n,1) ;
            }
        }
    }
    return 0 ;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

poj2892--Tunnel Warfare(线段树)

标签:

原文地址:http://blog.csdn.net/winddreams/article/details/46892187

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!