hdu_1698 Just a Hook
来源:互联网 发布:mac获取最高权限 编辑:程序博客网 时间:2024/06/05 03:15
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698
分析:
由样例输入输出可以看出来,这只胖子的肉钩的每个小段开始的时候是铜的。
所谓的线段树整段更新问题,即区域覆盖问题。这个时候要把线段树的节点的值定义为颜色类型。。不再是区间的和了(不然就超时了)。
结构体如下:
#define MAXN 100010struct Node{ int left,right; int num; //标记颜色。1,2,3,-1(表在这个区间段是混合颜色);}segTree[4*MAXN];
还有就是延迟更新问题。因为是一个段更新的,找到该段后先不更新段下面的节点,到了以后要改变该段的值的时候再改变其子节点的值(最好拿样例自己模拟一遍)。
如
1 5 2; 找到[1,5]改变值,下面的子区间不改变。
5 9 3;
到[1,5]的时候,因为要改变[5,5]的值,所有[1,5]变成了混合颜色,赋值为-1;
在赋值为-1之前,更新下面的节点[1,3],[4,5],这样子就可以减少不必要的更新了。
我的代码:
#include<stdio.h>#define MAXN 100010struct Node{ int l,r; int num; //标记是否是同一种颜色。}sT[4*MAXN];void build(int i,int l,int r){ sT[i].l=l; sT[i].r=r; if(l==r) { sT[i].num=1; return ; } int mid=(r+l)>>1; build(i<<1,l,mid); build(i<<1|1,mid+1,r); sT[i].num=1; //开始的时候都是颜色1.}void modfiy(int i,int a,int b,int m)//把[a,b]区间的位置改成颜色m{ //要明白在[a,b]是sT[i].l,sT[i].r的子集。 //所以当[a,b]的值等于sT[i].l,sT[i].r区间的值的时候,就直接返回; if(sT[i].num==m) return; //改的值和原来的一样,就不用改。 if(a==sT[i].l&&sT[i].r==b) { sT[i].num=m; return; } /**接下来,要改变[sT[i].l,sT[i].r]的值了 **如果此区间不是混合区间,就把他得值给左右孩子。 **这就是所谓的延迟更新,到了不得不更新的时候再跟新。 **/ if( sT[i].num!=-1) { sT[i<<1].num=sT[i<<1|1].num=sT[i].num; } sT[i].num=-1; //-1表混合区间 int mid=(sT[i].r+sT[i].l)>>1; if(b<=mid) { modfiy( i<<1, a, b, m); } else if(a>mid) { modfiy( i<<1|1, a, b, m); } else { modfiy( i<<1, a, mid, m); modfiy( i<<1|1, mid+1, b, m); }}int sumTree(int i,int a,int b){ //[a,b]是当前节点的子区间。 //如果这个大区间是一个值,则可以之间返回。 if(sT[i].num>0) //不是杂区间。 { return sT[i].num*(b-a+1); } int mid=(sT[i].r+sT[i].l)>>1; if(b<=mid) sumTree(i<<1,a,b); else if(a>mid) sumTree(i<<1|1,a,b); else return sumTree(i<<1,a,mid)+sumTree(i<<1|1,mid+1,b);}int main(){ int t,k; scanf("%d",&t); for(k=1;k<=t;k++) { int n,m; //[1,n]; scanf("%d%d",&n,&m); build(1,1,n); for(int j=0;j<m;j++) { int a,b,v; scanf("%d%d%d",&a,&b,&v); modfiy(1,a,b,v); } printf("Case %d: The total value of the hook is %d.\n",k,sumTree(1,1,n)); } return 0;}
总结:
一开始用线段树的节点的表示区间的总和,果断超时。这道题对线段树的维护与hdu_1166(敌兵布阵)是不一样的。本题是整段改变值,后者是点改变;本题是做一连串改变后输出总值,后者是改一改输出一下值。
也试过有hdu_1166的结构,每次改变叶子节点的值的时候,不往上更新,等所有叶子节点的都改变后,再从root节点往下更新区间的总和。一开始以为自己的思想有多棒o(≧v≦)o~~,还是超时了。
有事一种新线段树权值结构,还有的学。(*^__^*) 。
- hdu_1698 Just a Hook
- HDU_1698 Just a hook
- HDU_1698 Just a Hook(线段树+lazy标记)
- Just a Hook (HDU_1698) 线段树+区间更新
- hdu1698 Just a Hook
- HDU1689 Just a Hook
- Just a Hook
- hdu Just a Hook
- hdu1698 Just a Hook
- [HDU1698]Just a Hook
- hdu1698 Just a Hook
- Just a Hook
- Just a Hook
- Just a Hook
- hdu1698 Just a Hook
- HDU1698 Just a Hook
- HDU Just a Hook
- hdu1698 Just a Hook
- Android添加自定义广播事件(带多个参数)
- iphone开发中的一些小技巧
- 怎样从一名程序员过度到项目经理
- 角点检测和匹配之Harris与FAST角点检测
- Service与AlarmManager-BroadcastReceiver能否在CPU沉睡下工作
- hdu_1698 Just a Hook
- set常用操作简介
- Linq 插入问题 不能添加其键值已在使用中的实体
- 《GLIB C MANUAL》--1.1.入门
- 在同一个tomcat下,不同的web项目共享session
- 《初学cocos2d-x》- 容器CCArray(4)
- 建设全功能团队
- 以Facebook为案例剖析科技公司应有的工具文化
- C++ 虚函数表解析