zoj 1610 Count the Colors --线段树成段更新
2015-08-01 15:17
471 查看
题目链接点击打开链接
题意:对一条直线成段染色,求最后能看到的颜色以及每一种颜色的不连续段数。
思路:本题有两个难点。
第一:线段树的编号都是点,比如更新1-3更新1 2 3这三个点。二对于本题,更新1-3则表示更新1-2 和2-3这两个单位1的区间。解决的方法是把第二种更新方式改为第一种。只需要左端点值加1即可。
第二,如何统计同颜色不连续区间个数。如果每遇到一个颜色就对该颜色加1的话,很显然递归时相邻区间交界处如果颜色相同,会被重复计算。通过分析query函数发现,线段树采取类似后序遍历的方法。访问完一个区间后,接下来访问的区间必然是其右边相邻的区间。那么我们对当前区间颜色进行记录,判断访问下一个区间时判断两种颜色是否相等即可。
AC代码
题意:对一条直线成段染色,求最后能看到的颜色以及每一种颜色的不连续段数。
思路:本题有两个难点。
第一:线段树的编号都是点,比如更新1-3更新1 2 3这三个点。二对于本题,更新1-3则表示更新1-2 和2-3这两个单位1的区间。解决的方法是把第二种更新方式改为第一种。只需要左端点值加1即可。
第二,如何统计同颜色不连续区间个数。如果每遇到一个颜色就对该颜色加1的话,很显然递归时相邻区间交界处如果颜色相同,会被重复计算。通过分析query函数发现,线段树采取类似后序遍历的方法。访问完一个区间后,接下来访问的区间必然是其右边相邻的区间。那么我们对当前区间颜色进行记录,判断访问下一个区间时判断两种颜色是否相等即可。
AC代码
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<queue> #include<stack> #include<map> #include<algorithm> #include<iostream> #include<string> #pragma comment(linker, "/STACK:102400000,102400000") #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef long long ll; using namespace std; const ll maxn=1005; const int N = 100000; int col[N<<2],lazy[N<<2],sum ,pre; ///pre 存前面一段的颜色 void PushUp(int rt) { if(col[rt<<1]==col[rt<<1|1]) col[rt] = col[rt<<1]; else col[rt] = -1; } void PushDown(int rt) { if(lazy[rt]) { lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt]; col[rt<<1] = col[rt<<1|1] = lazy[rt]; lazy[rt] = 0; } } void build(int l,int r,int rt) { lazy[rt] = 0; if(l==r) { col[rt] = 0; return ; } int m = (l+r)>>1; build(lson); build(rson); PushUp(rt); } void update(int L,int R,int c,int l,int r,int rt) { if(L<=l && r<=R) { col[rt] = c; lazy[rt] = c; return ; } int m = (l+r)>>1; PushDown(rt); if(L<=m) update(L,R,c,lson); if(m<R) update(L,R,c,rson); PushUp(rt); } void query(int l,int r,int rt = 1) { if(col[rt]!=-1) { if(col[rt]!=pre) sum[col[rt]] ++ ; pre = col[rt] ; return ; } PushDown(rt); int m = (l+r)>>1; query(lson); query(rson); } int main() { int T,n,q,L,R,col,cs = 1,mx; while(~scanf("%d",&q)) { memset(sum,0,sizeof(sum)); mx = 0,pre = - 2; build(1,8000,1); while(q--) { scanf("%d%d%d",&L,&R,&col); L++; col ++ ; update(L,R,col,1,8000,1); mx = max(mx,col); } query(1,8000,1); for(int i=1;i<=mx;i++) { if(sum[i]) printf("%d %d\n",i-1,sum[i]); } puts(""); } return 0; }
相关文章推荐
- JQuery中$.ajax()方法参数详解
- SVD奇异值分解简析
- 杭电4883 TIANKENG’s restaurant(小板凳的问题)
- Label Button和textfield组合
- 使用Cadence绘制PCB流程(个人小结)
- POJ1064——二分——Cable master
- 按值传递对象和按址传递对象
- Redis 数据持久化
- Android 向右滑动销毁(finish)Activity, 随着手势的滑动而滑动的效果
- uva10305(拓扑
- 第六天 抽象类和接口
- HDU 4986/BC 7B Little Pony and Alohomora Part I
- 数据库设计--实体关系图(ERD)
- Java 多线程 并发编程
- android mvp模式
- MySQL性能优化总结
- HDU2141——二分——Can you find it?
- 数据结构 线性表的顺序存储
- Lucene八(搜索分 4000 页)
- 高效Linux之Terminal下实用快捷键