HDU 1698 Just a Hook(线段树-区间修改|区间查询)
2015-09-25 20:29
531 查看
该题是线段树区间修改和区间查询的模板题,需要仔细理解模板中的setv数组和sumv数组,sumv数组定义为:如果只执行结点o及其子孙结点中的setv操作,结点o对应区间中所有数只和。 setv数组就是所谓的懒惰标记,我们不是每次修改值都遍历所有涉及到的区间,而是在查询时用到了哪个setv值之时临时更新。
还有一些细节没有搞懂,明白之后再回来补充。
细节参见代码:
还有一些细节没有搞懂,明白之后再回来补充。
细节参见代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<vector> #include<map> using namespace std; const int maxn = 100000 + 5; int T,n,q,y11,y22,v,kase=0,_sum,sumv[3*maxn],setv[maxn*3]; void pushdown(int o) { int lc = o*2, rc = o*2+1; if(setv[o] >= 0) { setv[lc] = setv[rc] = setv[o]; setv[o] = -1; } } void maintain(int o, int L, int R) { int lc = o*2, rc = o*2+1; sumv[o] = 0; if(R > L) { sumv[o] = sumv[lc] + sumv[rc]; } if(setv[o]>=0) sumv[o] = setv[o]*(R-L+1); } void update(int o, int L, int R) { int lc = o*2, rc = o*2+1; if(y11 <= L && y22 >= R) { setv[o] = v; } else { pushdown(o); int M = L + (R-L)/2; if(y11 <= M) update(lc, L, M); else maintain(lc, L, M); if(y22 > M) update(rc, M+1, R); else maintain(rc, M+1, R); } maintain(o, L, R); } void query(int o, int L, int R) { if(setv[o] >= 0) { _sum += setv[o] * (min(R,y22)-max(L,y11)+1); } else if(y11 <= L && y22 >= R) { _sum += sumv[o]; } else { int M = L + (R-L)/2; if(y11 <= M) query(o*2, L, M); if(y22 > M) query(o*2+1, M+1, R); } } int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&q); v = 1; y11 = 1; y22 = n; update(1,1,n); while(q--) { scanf("%d%d%d",&y11,&y22,&v); update(1,1,n); } _sum = 0; y11 = 1; y22 = n; query(1,1,n); printf("Case %d: The total value of the hook is %d.\n",++kase,_sum); } return 0; }
相关文章推荐
- 如何用Netbeans加背景图片
- SlickGrid 插件开发(2):单元格合并功能实现
- Websphere设备、企业部署应用程序 【应用】
- 双月楼月饼荣获茂名在线月饼品鉴佳绩
- 我要上蓝翔 1702 (广搜)
- 软考视频总结(二)——细化学习A
- 二维数组的反转
- GLSL 数据类型和限定符
- MySQL查看当前数据库库
- linux下svn命令使用大全
- HDU 4219 Randomization?(树形概率DP)
- LintCode 不同的路径 II
- CentOS安装Memcached
- WAJUEJI which home strong! 1100 (广搜)
- 教你使用vim表白
- html5 canvas标签
- 1.C++顺序表
- Circle - SGU 130(递推)
- setup.s
- 《机器学习与R语言》读书笔记2:使用R进行机器学习