POJ 3468 A Simple Problem with Integers (线段树—成段覆盖)
来源:互联网 发布:c语言判断数字大小 编辑:程序博客网 时间:2024/06/05 18:44
题意:给出[1,n]区间内每个点的数值,让你执行下面的操作:
1. C a b w : 区间[a,b]上所有点的数值加上w。
2. Q a b : 输出区间[a,b]上所有点的数值之和。
思路:经典线段树。静态建树,成段修改,区间求和。用普通的线段树去做肯定超时,因为成段修改的时候会是o(n)。关键在于用add记录对应区间内所有元素的增量,并对查询函数进行相应的修改。注意修改和查询的一个很关键的性质:区间[node[u].left,node[u].right]必定包含区间[left,right]。
//7088K 2219MS#include <stdio.h>#include <string.h>#define N 100050#define MAX(X,Y) ( (X) > (Y) ? (X) : (Y) )#define MIN(X,Y) ( (X) < (Y) ? (X) : (Y) )#define L(X) ( (X) <<1 )#define R(X) ( ( (X) << 1 )| 1 )#define MID(X) ( (X)>>1 )struct node{ int left , right ; double sum , add ; // sum存储区间数值之和,add存储区间内所有数的增量。}node[4*N];double num[N] ;double ans ;void BuildTree ( int const left , const int right , int n ){ node[n].left = left ; node[n].right = right ; node[n].add = 0 ; if ( left == right ) { node[n].sum = num[left] ; } else { int mid ; mid = MID ( left + right ) ; BuildTree ( left , mid , L(n)) ; BuildTree ( mid + 1 , right , R(n) ) ; node[n].sum = node[L(n)].sum + node[R(n)].sum ; }}void Update ( int const left , int const right , double const val , int n ){ if ( node[n].left == left && node[n].right == right ) { node[n].add += val ; // 情况1:两区间完全匹配,新增的值记录为区间的add。 return ; } node[n].sum += ( right - left + 1 ) * val ; // 情况2:区间要继续分割,大区间的sum加上小区间所有数值新增的总和。 if ( left <= node[L(n)].right ) // 区间分割要考虑全面。 { int temp_r ; temp_r = MIN( node[L(n)].right , right ) ; Update ( left , temp_r , val , L(n) ) ; } if ( right >= node[R(n)].left ) // 区间分割要考虑全面。 { int temp_l ; temp_l = MAX( left , node[R(n)].left ) ; Update ( temp_l , right , val , R(n) ) ; }}void Query ( int const left , int const right , int const n ){ ans += ( right - left + 1 ) * node[n].add ; // 先加上区间[left,right]记录在[node[i].l,node[i].r]的总增量。 if ( node[n].left == left && node[n].right == right ) // 情况1:两区间完全匹配。 { ans += node[n].sum ; } else if ( right <= node[L(n)].right ) // 情况2:小区间被大区间的左子区间包含。 { Query ( left , right , L(n) ) ; } else if ( left >= node[R(n)].left) // 情况3:小区间被大区间的右子区间包含。 { Query ( left , right , R(n) ) ; // 情况4:小区间被大区间的两个子区间分割。 } else { int mid ; mid = MID ( node[n].left + node[n].right ) ; Query ( left , mid , L(n) ) ; Query ( mid + 1 , right , R(n) ) ; }}intmain ( ){ int n , m ; scanf ("%d%d" , & n , & m ) ; int i ; for ( i = 1 ; i <=n ; i ++ ) { scanf ("%lf" , & num[i] ) ; } getchar ( ) ; BuildTree ( 1 , n , 1 ) ; while ( m -- ) { char oper ; int left , right ; scanf ("%c" , & oper ) ; if ( oper == 'Q' ) { scanf ("%d%d" , & left , & right ) ; ans = 0 ; Query ( left , right , 1 ) ; printf ("%.0f\n" , ans ) ; } else { double val ; scanf ("%d%d%lf" , & left , & right , & val ) ; Update ( left , right , val , 1 ) ; } getchar( ) ; } return 0 ;}
- POJ 3468 A Simple Problem with Integers (线段树—成段覆盖)
- 线段树模板(二)——成段更新 + POJ 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers(线段树|成段更新,区间查询)
- poj 3468 A Simple Problem with Integers(线段树,成段更新)
- poj 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)
- POJ 3468 A Simple Problem with Integers 线段树 (成段更新)
- [ACM] poj 3468 A Simple Problem with Integers(线段树,成段更新,懒惰标记)
- 线段树(成段更新) 之 poj 3468 A Simple Problem with Integers
- POJ 3468-A Simple Problem with Integers(线段树:成段更新,区间求和)
- POJ 3468 A Simple Problem with Integers(线段树 成段更新)
- POJ - 3468 - A Simple Problem with Integers (线段树 - 成段更新)
- POJ 3468 A Simple Problem with Integers(线段树 成段增减,区间求和)
- POJ 3468 A Simple Problem with Integers 线段树(成段更新)
- poj 3468 -- A Simple Problem with Integers ( 线段树 , 段更新 , 段求和 )
- 线段树 POJ 3468 A Simple Problem with Integers 线段树 成段更新入门
- POJ 3468 A Simple Problem with Integers 线段树 成段更新
- POJ 3468 A Simple Problem with Integers //线段树的成段更新
- poj 3468 A Simple Problem with Integers (线段树---成段更新)
- 排序算法之插入排序
- C++: Accessing the virtual table directly(盗版)
- 什么是 ant----编译打包工具 ant
- Linux 静态库与共享库
- gdal的矢量栅格化接口GDALRasterizeLayers使用(一)
- POJ 3468 A Simple Problem with Integers (线段树—成段覆盖)
- C++的I/O(vc版)(六)
- Myeclipse 导入 tomcat 源码
- oracle vpd 虚拟专用数据库
- Boost下载安装编译配置使用指南(含Windows、Linux以及ARM Linux)
- Linux2.6 内核进程调度分析
- windows下 直接点击startup.bat 启动tomcat服务
- CSS3之圆角border-radius
- 《C++游戏开发》十七 游戏中的寻路算法(三):A*算法原理