hdu 1540 线段树+区间合并

来源:互联网 发布:怎样学软件 编辑:程序博客网 时间:2024/05/17 07:57

每个线段维护左起连续长度,和右起连续长度,然后每次查询时讨论x所在连续段是否同时存在两个子段中,分类讨论即可

#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <stack>#define MAX 50007using namespace std;int n,m,a;char s[5];stack<int> stk;struct Tree{    int l , r , llen , rlen;}tree[MAX<<2];void build ( int u , int l , int r ){    tree[u].l = l , tree[u].r = r;    tree[u].llen = tree[u].rlen = r-l+1;    if ( l == r ) return;    int mid = l + r >> 1;    build ( u<<1 , l , mid );    build ( u<<1|1 , mid+1 , r );}void push_up ( int u ){    tree[u].llen = tree[u<<1].llen;    tree[u].rlen = tree[u<<1|1].rlen;    if ( tree[u<<1].llen == tree[u<<1].r - tree[u<<1].l + 1 )       tree[u].llen = tree[u<<1].llen + tree[u<<1|1].llen;    if ( tree[u<<1|1].rlen == tree[u<<1|1].r - tree[u<<1|1].l + 1 )       tree[u].rlen = tree[u<<1].rlen + tree[u<<1|1].rlen;         }void update ( int u , int x , int v){    int l = tree[u].l , r = tree[u].r;    if ( l == r )    {        tree[u].llen =  tree[u].rlen = v;        return;    }    int mid = l + r >> 1;    if ( x > mid ) update ( u<<1|1 , x , v );    else update ( u<<1 , x , v );    push_up ( u );}int query ( int u , int x ){    int l = tree[u].l , r = tree[u].r;    if ( r-l+1 == tree[u].llen )        return r-l+1;    if ( l == r )        return tree[u].llen;    int mid = l + r >> 1;    if ( x > mid )    {        if ( tree[u<<1|1].l + tree[u<<1|1].llen > x )           return query ( u<<1|1 , x ) + tree[u<<1].rlen;         else return query ( u<<1|1 , x );     }    else    {        if ( tree[u<<1].r - tree[u<<1].rlen < x )            return query ( u<<1 , x ) + tree[u<<1|1].llen;        else return query ( u<<1 , x );    }}int main ( ){    while ( ~scanf ( "%d%d" , &n , &m ) )    {        build ( 1 , 1 , n );        while ( !stk.empty() ) stk.pop();        for ( int i = 0 ; i < m ; i++ )        {            scanf ( "%s" , s );            if ( s[0] == 'D' )            {                scanf ( "%d" , &a );                update ( 1 , a , 0 );                stk.push ( a );            }            else if ( s[0] == 'Q' )            {                scanf ( "%d" , &a );                printf ( "%d\n" , query ( 1 , a ) );            }            else            {                update ( 1 , stk.top() , 1 );                stk.pop ( );            }        }       }}


0 0