hdu 3308 线段树区间更新

来源:互联网 发布:翻墙工具 for mac 编辑:程序博客网 时间:2024/06/03 15:58
<span style="font-family: Arial, Helvetica, sans-serif;">#include<iostream></span>
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<queue>#include<cstdlib>using namespace std;struct  Node{    int l_value,r_value;             //左端点,右端点值    int l_max,r_max; <span style="white-space:pre"></span>     //  左,右端点开始的最大LCIS     int l,r,max; <span style="white-space:pre"></span>     // 区间的左右端点位置  max值指该区间内最大的LCIS  (可能是l_max  r_max中之一)};Node tree[400024];int num[100024];int Max( int a , int b ){    return a>b? a:b;}Node Update( Node a ,Node b )          //整段代码的重中之重   其他的操作都是很常见且很容易理解的  关于在于区间的合并操作。{    Node t;    t.l=a.l,t.r=b.r;    t.l_value=a.l_value;                 //首先由左右孩子更新父亲的左右端点的值,也更新左右端点的位置    t.r_value=b.r_value;    if(a.r_value<b.l_value&&a.l_max==(a.r-a.l+1))     //如果左孩子的左端点开始的LCIS值是整个左孩子长度 同时左孩子右端点值小于右孩子左端点值 此时更新父亲节点的左端点开始的LCIS 长度为两个孩子的左端点和        t.l_max=a.l_max+b.l_max;     else t.l_max=a.l_max;      //如果左右孩子无法连接   那么单独更新    if(a.r_value<b.l_value&&b.r_max==(b.r-b.l+1))        t.r_max=a.r_max+b.r_max;    else t.r_max=b.r_max;         //右孩子操作同左孩子一样      if(a.r_value<b.l_value)        t.max=Max(Max(a.max,b.max),a.r_max+b.l_max);    //  更新父亲的max值   如果可以连接   那么max值的来源有三项  否则两项    else t.max=Max(a.max,b.max);    return t;}void Maketree( int l , int r, int cnt ){    tree[cnt].l = l;    tree[cnt].r = r;    tree[cnt].l_value = num[l];    tree[cnt].r_value = num[r];    if( l == r )    {        tree[cnt].l_max = tree[cnt].r_max = tree[cnt].max = 1;        return ;    }    int mid = ( l + r )>>1;    Maketree( l , mid  ,cnt*2 );    Maketree( mid + 1 , r , cnt*2+1);    tree[cnt] = Update( tree[cnt*2] , tree[cnt*2+1] );}void Change( int place ,int value, int cnt ){    if( place == tree[cnt].l&&tree[cnt].r == place )    {        tree[cnt].r_value = tree[cnt].l_value = value;        return ;    }    int mid = ( tree[cnt].r + tree[cnt].l )>>1;    if( place > mid ) Change( place , value , cnt*2+1 );    else Change( place ,value , cnt*2 );    tree[cnt] = Update( tree[cnt*2] , tree[cnt*2+1] );}Node Query( int l , int r, int cnt ){    if( l<=tree[cnt].l&&r>=tree[cnt].r )        return tree[cnt];    int mid = (tree[cnt].l + tree[cnt].r)>>1;    if( l > mid  ) return Query( l , r , cnt*2+1 );    else if( r <= mid ) return Query( l ,r ,cnt *2  );    else    {        Node a,b;        a = Query( l , mid , cnt*2 );        b = Query( mid + 1, r ,cnt*2 + 1);        return Update( a ,b );    }}int main( ){    int n,N,m,A,B;    char c[4];    while( scanf( "%d",&N )==1 )    {        while( N-- )        {            scanf( "%d%d",&n,&m );            for( int i = 0; i< n ;i++ )                scanf( "%d",&num[i] );            Maketree( 0 , n-1 , 1 );            for( int i = 0 ; i< m ; i++ )            {                scanf( "%s%d%d",c , &A ,&B );                if( c[0]=='U' )                {                    Change( A , B , 1 );                }                else                {                    Node t = Query( A , B ,1 );                    printf( "%d\n",t.max );                }            }        }    }    return 0;}

0 0
原创粉丝点击