ACM集训--HDU 1166
来源:互联网 发布:ubuntu 覆盖安装 编辑:程序博客网 时间:2024/05/17 23:24
线段树模板题:
hdu1166,先摆模板:
(1):线段树的构造 void build(int l, int r, int rt);
主要思想是递归构造,如果当前节点记录的区间只有一个值,则直接赋值,否则递归构造左右子树,最后回溯的时候给当前节点赋值
<span style="font-family:Comic Sans MS;">void Build(int l, int r, int rt) { if(l == r) { scanf("%d", &sum[rt]); return ; } int m = ( l + r )>>1; Build(lson); Build(rson); PushPlus(rt); }</span>
(2):区间查询int query(int node, int begin, int end, int left, int right);
(其中node为当前查询节点,begin,end为当前节点存储的区间,left,right为此次query所要查询的区间)
主要思想是把所要查询的区间[a,b]划分为线段树上的节点,然后将这些节点代表的区间合并起来得到所需信息
<span style="font-family:Comic Sans MS;">int query(int node, int begin, int end, int left, int right) { int p1, p2; /* 查询区间和要求的区间没有交集 */ if (left > end || right < begin) return -1; /* if the current interval is included in */ /* the query interval return segTree[node] */ if (begin >= left && end <= right) return segTree[node]; /* compute the minimum position in the */ /* left and right part of the interval */ p1 = query(2 * node, begin, (begin + end) / 2, left, right); p2 = query(2 * node + 1, (begin + end) / 2 + 1, end, left, right); /* return the expect value */ if (p1 == -1) return p2; if (p2 == -1) return p1; if (p1 <= p2) return p1; return p2; } </span><span style="font-family:FangSong_GB2312;"></span>
a:单节点更新
<span style="font-family:Comic Sans MS;">void Updata(int node, int begin, int end, int ind, int add)/*单节点更新*/ { if( begin == end ) { segTree[node] += add; return ; } int m = ( left + right ) >> 1; if(ind <= m) Updata(node * 2,left, m, ind, add); else Updata(node * 2 + 1, m + 1, right, ind, add); /*回溯更新父节点*/ segTree[node] = min(segTree[node * 2], segTree[node * 2 + 1]); } </span><span style="font-family: FangSong_GB2312; "> </span>HDU1166用的就是单节点更新
<span style="font-family:Comic Sans MS;">#include<cstring> #include<iostream> #define M 50005 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 /*left,right,root,middle*/ int sum[M<<2]; inline void PushPlus(int rt) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } void Build(int l, int r, int rt) { if(l == r) { scanf("%d", &sum[rt]); return ; } int m = ( l + r )>>1; Build(lson); Build(rson); PushPlus(rt); } void Updata(int p, int add, int l, int r, int rt) { if( l == r ) { sum[rt] += add; return ; } int m = ( l + r ) >> 1; if(p <= m) Updata(p, add, lson); else Updata(p, add, rson); PushPlus(rt); } int Query(int L,int R,int l,int r,int rt) { if( L <= l && r <= R ) { return sum[rt]; } int m = ( l + r ) >> 1; int ans=0; if(L<=m ) ans+=Query(L,R,lson); if(R>m) ans+=Query(L,R,rson); return ans; } int main() { int T, n, a, b; scanf("%d",&T); for( int i = 1; i <= T; ++i ) { printf("Case %d:\n",i); scanf("%d",&n); Build(1,n,1); char op[10]; while( scanf("%s",op) &&op[0]!='E' ) { scanf("%d %d", &a, &b); if(op[0] == 'Q') printf("%d\n",Query(a,b,1,n,1)); else if(op[0] == 'S') Updata(a,-b,1,n,1); else Updata(a,b,1,n,1); } } return 0; } </span>
要学会使用模板,必须好好的理解算法,至少要明确每个变量的意义,思路清晰了,代码也就不是问题
参考http://blog.csdn.net/metalseed/article/details/8039326
0 0
- ACM集训--HDU 1166
- ACM集训的开端!!!
- ACM集训记
- acm集训1
- ACM 集训总结
- ACM暑假集训(0)
- ACM暑假集训方法
- ACM集训第二天
- ACM集训--打字训练
- ACM集训day1
- ACM集训day2
- ACM集训day3
- ACM集训day4
- ACM集训day5
- ACM集训day6
- ACM集训day7
- ACM集训day8
- ACM集训day9
- 修改fstab配置项, 自动挂载分区
- ural 1550 Dean's Pyramid 3计算几何
- 表格排序
- 转:纽约时报揭密苹果公司内部培训项目=
- POJ3189 最大流
- ACM集训--HDU 1166
- cmd常用命令
- block 和 属性
- ubuntu下解决longene-qq 退出之后再登录出现登录失败的问题
- easyui问题小结
- 数据挖掘软件
- javafx 之获取fxml的控制器(controller)
- 微信中接收的word文件如何保存到电脑
- Evaluate Reverse Polish Notation