poj2892--Tunnel Warfare(线段树)

来源:互联网 发布:中国税务网络大学ipad 编辑:程序博客网 时间:2024/05/18 02:00

题目链接:点击打开链接

题目大意:给出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 0x3f3f3f3fint 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 ;}


1 0