POJ 2777 Count Color
来源:互联网 发布:c语言32个关键词 编辑:程序博客网 时间:2024/06/05 23:51
【题意】
给定n段,分别编号为1、2、……、n。初始化时都涂色为1,现在规定两中操作:
1)C A B C,给编号为A和B段涂色C
2)P A B,输出编号A到B段的涂色数
现在给定T为颜色的种类数(1——T)和O为操作总数,要求按照相应的操作输出P A B。
【分析如下】
令线段树节点定义为: l,r,value,flag分被表示区间左右端点,该区间的涂色为value,flag为标记量,true表示该区间涂色为最新的涂色,否则表示该区间的子区间有更新的涂色。由于初始时均涂色为1,故value的值均为1,flag均为true(即都是最新的涂色)。本题的难点在于更新和查找。
线段树的更新:寻找输入的涂色区域,在寻找的过程中若发现节点的flag为true,则要先更新子节点的value和flag然后更新自身的value和flag(注意顺序不能反了),当查找到区间时,直接赋值value和更新flag为true。
线段树的查找:线段树的更新和查找是联系起来的,这里主要说明一下查找的技巧:
朴素的查找就是边查找边更新,直到找到与查找路径相同的区间为止,其实这样得不偿失,消费了许多时间在无用的更新操作上,也使查找深度加深,所以可以只要flag为true,而不管该线段树区间时等于查找区间还是大于查找区间,由于是最新的涂色而且必定包含查找区间,故可以直接判断该涂色,并返回。这是查找关键,没有这一步就等着TLE。
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define max(a,b) return a>b?a:b#define min(a,b) return a<b?a:b#define NN 100010#define MM 40struct node{ int l,r,val,flag;}Tree[NN<<2];bool check[MM];//标记每次查找时颜色是否存在int L,T,O;int ans;//每次查询的答案void Build(int l,int r,int rt){ Tree[rt].l=l,Tree[rt].r=r,Tree[rt].val=1,Tree[rt].flag=true; if(l==r) return ; int m = (l+r)>>1; Build(l,m,rt<<1); Build(m+1,r,rt<<1|1);}void Push_Down(int rt)//延迟标记,更新路径上的次最新涂色点,先儿子后父亲{ if(Tree[rt].flag) { Tree[rt<<1].val = Tree[rt].val; Tree[rt<<1|1].val = Tree[rt].val; Tree[rt].flag = false;//不是最新的涂色点了 Tree[rt<<1].flag = true; //是最新的涂色点 Tree[rt<<1|1].flag = true; }}void Update(int l,int r,int val,int rt){ if(l==Tree[rt].l&&r==Tree[rt].r) { Tree[rt].val = val; Tree[rt].flag = true; return ; } else{ Push_Down(rt); int m = (Tree[rt].l+Tree[rt].r)>>1; if(r<=m) Update(l,r,val,rt<<1); else if(l>=m+1) Update(l,r,val,rt<<1|1); else { Update(l,m,val,rt<<1); Update(m+1,r,val,rt<<1|1); } }}void query_ans(int l,int r,int rt){ if(Tree[rt].flag)//只要区间包含就可判断查找区间颜色 { if(!check[Tree[rt].val]) { check[Tree[rt].val] = true; ans++; } return ; } int m =(Tree[rt].l+Tree[rt].r)>>1; if(r<=m) query_ans(l,r,rt<<1); else if(l>=m+1) query_ans(l,r,rt<<1|1); else { query_ans(l,m,rt<<1); query_ans(m+1,r,rt<<1|1); }}int main(){ while(~scanf("%d%d%d",&L,&T,&O)) { getchar(); Build(1,L,1); int a,b,c; char tmp; for(int i=0; i<O; i++) { tmp = getchar(); if(tmp=='C') { scanf("%d%d%d",&a,&b,&c); if(a>b)swap(a,b); Update(a,b,c,1); }else{ scanf("%d%d",&a,&b); memset(check,false,sizeof(check));//每次都初始化为出现 ans = 0; if(a>b)swap(a,b); query_ans(a,b,1); printf("%d\n",ans); } getchar(); } } return 0;}
1 0
- POJ 2777 Count Color
- poj 2777 Count Color
- poj 2777 count color
- poj 2777 Count color
- poj 2777 Count Color
- Poj 2777 Count Color
- POJ 2777 Count Color
- poj 2777 count color
- POJ 2777 Count Color
- poj 2777 Count Color
- poj 2777 count color
- poj 2777 Count Color
- poj 2777 Count Color
- POJ 2777 Count Color
- poj 2777 Count Color
- poj 2777 Count Color
- POJ--2777--Count Color
- Count Color poj 2777
- iOS tableView 添加索引后 索引遮盖 headview 解决办法
- linux与window共享-Samba安装
- jq制作banner 滚动
- phpstorm 8 license key
- java中applet小程序的数字签名
- POJ 2777 Count Color
- Android animator
- 整合网上资源 整理的 Alfred 2 的配置教程
- myeclipse6.0安装maven插件
- wampserver和mysql administrator共同使用
- easyUI 增删查改1
- HTML5特效源码网站
- 数据结构(15)--哈夫曼树以及哈夫曼编码的实现
- APP启动页的正确配置方式