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
- hdu 3308 线段树 区间更新 LICS
- HDU 3308 LCIS 线段树区间更新
- hdu 3308 线段树区间更新
- hdu 3308 LCIS (线段树+单点更新+区间合并)
- hdu 3308 线段树单点更新 区间合并
- hdu.3308 LCIS(线段树,区间合并+单点更新)
- HDU 3308 LCIS(线段树区间合并 单点更新)
- HDU 3308 LCIS 线段树的单点更新,区间合并
- HDU 1698 区间更新线段树
- hdu 4578 Transformation [线段树 区间更新]
- hdu 1698 线段树区间更新
- hdu 2795 线段树,区间更新求补值
- HDU 1698 【线段树区间更新】
- HDU 1698(线段树区间更新)
- hdu 1698 线段树 区间更新
- HDU 1698 线段树区间更新模板
- HDU 1698(线段树 区间更新)
- HDU 4578(线段树区间更新)
- 问题and解决:ORA-12154: TNS: 无法解析指定的连接标识符
- 学习笔记:ios手势(滑动)返回
- JUnit4 中@AfterClass @BeforeClass @after @before的区别对比
- jquery 选择器空格,加号,大于号,波浪号的区别
- CSS样式ul与li标签属性与布局技巧
- hdu 3308 线段树区间更新
- 2014上学期总结
- java 三大框架整合
- Axure tab切换 学习笔记
- LDA
- HDU 1285----确定比赛名次
- Android快速开发系列 10个常用工具类
- 【架构】为什么在服务层设计读写分离
- 实现PHP+Mysql无限分类的方法汇总