F - Count the Colors
2016-03-24 16:16
393 查看
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=66989#problem/F
线段树入门,起初,设置数组sum=-1表示无颜色,sum=-2表示下方无统一颜色;sum>=0表示颜色为sum的占据了整个子树
li ri数组==-1,-1表示左右无统一颜色其他表示区间rt左边颜色为li右边为ri,这样既可实现本题
看代码
吃个饭回来好像明白了些什么了,rili数组干嘛的。。。明显上面的代码没有用,然后根据后序遍历树个特点(神奇的地方)设置一个前驱temp,刚刚好解决了上面的问题,4的前驱刚好是3。代码贴上
线段树入门,起初,设置数组sum=-1表示无颜色,sum=-2表示下方无统一颜色;sum>=0表示颜色为sum的占据了整个子树
li ri数组==-1,-1表示左右无统一颜色其他表示区间rt左边颜色为li右边为ri,这样既可实现本题
看代码
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <map> #include <set> #include <stack> #include <string> #define SI(T)int T;scanf("%d",&T) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define LL long long using namespace std; const int SIZE=5; const int maxn=1<<30; int sum[SIZE<<2],li[SIZE<<2],ri[SIZE<<2]; int cnt[SIZE]; void pushup(int rt){ if(sum[rt<<1]!=-1||sum[rt<<1|1]!=-1){ li[rt]=ri[rt]=-1; sum[rt]=-2; return; } if(ri[rt<<1]==li[rt<<1|1]){ sum[rt]=li[rt]=ri[rt]=ri[rt<<1]; } } void pushdown(int rt){ if(sum[rt]>0){ sum[rt<<1]=sum[rt<<1|1]=sum[rt]; sum[rt]=-2; } } void build(int l,int r,int rt){ memset(sum,-1,sizeof(sum)); memset(li,-1,sizeof(li)); memset(ri,-1,sizeof(ri)); } void update(int L,int R,int c,int l,int r,int rt){ if(L<=l&&r<=R){ sum[rt]=li[rt]=ri[rt]=c; return; } pushdown(rt); int m=(l+r)>>1; if(L<=m)update(L,R,c,lson); if(R>m)update(L,R,c,rson); pushup(rt); } void query(int l,int r,int rt){ if(sum[rt]>0){ cnt[sum[rt]]++; return ; } if(sum[rt]==-1)return; int m=(l+r)>>1; if(l<=m)query(lson); if(r>m)query(rson); } int main() { int n,x1,x2,c; while(scanf("%d",&n)!=EOF){ memset(cnt,0,sizeof(cnt)); build(1,SIZE,1); for(int i=0;i<n;i++){ scanf("%d%d%d",&x1,&x2,&c); update(x1+1,x2,c,1,SIZE,1); } query(1,SIZE,1); for(int i=0;i<SIZE<<1;i++) printf("%d %d\n",sum[i],i); for(int i=0;i<SIZE;i++){ if(cnt[i]){ printf("%d %d\n",i,cnt[i]); } } } return 0; }但是要是更新的是3跟4区间从二叉树上看3跟4区间分隔在了两颗子树,虽然他们在线上是链接的,但是在线段树上却是断开的,导致了错误。
吃个饭回来好像明白了些什么了,rili数组干嘛的。。。明显上面的代码没有用,然后根据后序遍历树个特点(神奇的地方)设置一个前驱temp,刚刚好解决了上面的问题,4的前驱刚好是3。代码贴上
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <map> #include <set> #include <stack> #include <string> #define SI(T)int T;scanf("%d",&T) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define LL long long using namespace std; const int SIZE=8080; const int maxn=1<<30; int sum[SIZE<<2]; int cnt[SIZE]; int temp; void pushup(int rt){ if(sum[rt<<1]==-2||sum[rt<<1|1]==-2){ sum[rt]=-2; return; } if(sum[rt<<1]==sum[rt<<1|1])sum[rt]=sum[rt<<1]; else sum[rt]=-2; } void pushdown(int rt){ if(sum[rt]>=0){ sum[rt<<1]=sum[rt<<1|1]=sum[rt]; sum[rt]=-2; } } void build(int l,int r,int rt){ sum[rt]=-1; if(l==r)return; int m=(l+r)>>1; build(lson); build(rson); } void update(int L,int R,int c,int l,int r,int rt){ if(L<=l&&r<=R){ sum[rt]=c; return; } pushdown(rt); int m=(l+r)>>1; if(L<=m)update(L,R,c,lson); if(R>m)update(L,R,c,rson); pushup(rt); } void query(int l,int r,int rt){ if(sum[rt]>=0){ if(temp==sum[rt])return; temp=sum[rt]; cnt[sum[rt]]++; return ; } if(sum[rt]==-1){temp=-1;return;} int m=(l+r)>>1; if(l<=m)query(lson); if(r>m)query(rson); } int main() { int n,x1,x2,c; while(scanf("%d",&n)!=EOF){ memset(cnt,0,sizeof(cnt)); build(1,SIZE,1); for(int i=0;i<n;i++){ scanf("%d%d%d",&x1,&x2,&c); update(x1+1,x2,c,1,SIZE,1); } temp=-1; query(1,SIZE,1); for(int i=0;i<SIZE;i++){ if(cnt[i]){ printf("%d %d\n",i,cnt[i]); } } printf("\n"); } return 0; }
相关文章推荐
- ubuntu下使用OBS开斗鱼直播
- cssHack
- 学习、阅读笔记——jsonP&Ajax
- java中的强、软、弱和虚引用
- String与InputStream的互相转换
- SecureCRT远程登录ubuntu
- Python datetime的简单使用
- 204. Count Primes
- 高性能网关设备及服务实践
- PHP操作SQLITE
- SVN的使用
- MongoDB 2.6.x 的安装部署
- C++中求类的大小
- ElasticSearch 2 (33) - 信息聚合系列之聚合过滤
- css3中的边框相关样式
- hive json数据生成和处理
- SQL的四种连接-左外连接、右外连接、内连接、全连接
- 每天一个linux命令(60):scp命令 【转】
- Neural Net 感悟 1
- 对象的访问定位