【HDU1199】 离散化线段树
2013-04-27 23:27
411 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1199
题目大意: 一段长度未知的线段,一种操作:a b c ,表示区间[a,b]要涂的颜色,c=w涂白色,c=b涂黑色,问你最长的白色区间段时多长。
解题思路:
就快去南京邀请赛了,最近做题超没状态,CF rating一直掉,这么简单的线段树离散化居然搞了我一个晚上,纠结。
开始用线段树区间合并的方法做,WA到死,换个写法,又WA到死,没处理好边界问题。
这题用普通的离散化没用,藐视这种离散化第一次遇见,以前的离散化要么就是点化点,线段化点,这题不一样,是点化线段,一不小心处理不好就WA了。
点化线段我利用的是左闭右开,即对于一段区间[a,b],转化成区间[a,b+1),接下来就是把所有端点当做简单的离散化处理了,然后运用线段树成段更新操作处理就好了。
View Code
题目大意: 一段长度未知的线段,一种操作:a b c ,表示区间[a,b]要涂的颜色,c=w涂白色,c=b涂黑色,问你最长的白色区间段时多长。
解题思路:
就快去南京邀请赛了,最近做题超没状态,CF rating一直掉,这么简单的线段树离散化居然搞了我一个晚上,纠结。
开始用线段树区间合并的方法做,WA到死,换个写法,又WA到死,没处理好边界问题。
这题用普通的离散化没用,藐视这种离散化第一次遇见,以前的离散化要么就是点化点,线段化点,这题不一样,是点化线段,一不小心处理不好就WA了。
点化线段我利用的是左闭右开,即对于一段区间[a,b],转化成区间[a,b+1),接下来就是把所有端点当做简单的离散化处理了,然后运用线段树成段更新操作处理就好了。
View Code
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define lz 2*u,l,mid #define rz 2*u+1,mid,r ///注意:这里是点化为线段(左闭右开) const int maxn=5555; const int oo=0x3fffffff; int flag[4*maxn], color[maxn]; int X[maxn]; struct Node { int lx, rx, s; Node(){} Node(int lx_, int rx_, int s_) { lx=lx_, rx=rx_, s=s_; } }line[maxn]; void push_down(int u, int l, int r) { if(flag[u]==-1) return ; else { flag[2*u]=flag[2*u+1]=flag[u]; flag[u]=-1; } } void Update(int u, int l, int r, int tl, int tr, int c) { if(tl>=tr) return ; ///这里要注意了 if(tl<=l&&r<=tr) { flag[u]=c; return ; } push_down(u,l,r); int mid=(l+r)>>1; if(tr<=mid) Update(lz,tl,tr,c); else if(tl>mid) Update(rz,tl,tr,c); else { Update(lz,tl,mid,c); Update(rz,mid,tr,c); } } void Query(int u, int l, int r) { if(l>=r) return ; ///!!! if(flag[u]!=-1) { for(int i=l; i<r; i++) color[i]=flag[u]; ///右端点不标记 return ; } push_down(u,l,r); int mid=(l+r)>>1; Query(lz); Query(rz); } int find(int tmp, int n) { int l=1, r=n, mid; while(l<=r) { mid=(l+r)>>1; if(X[mid]==tmp) return mid; else if(X[mid]<tmp) l=mid+1; else r=mid-1; } } int main() { int n, x, y, c; char ch[3]; while(~scanf("%d",&n)) { int num=0; for(int i=0; i<n; i++) { scanf("%d%d%s",&x,&y,ch); if(*ch=='w') c=1; else c=0; line[i]=Node(x,y+1,c); X[++num]=x; X[++num]=y+1; } sort(X+1,X+num+1); int ep=1; for(int i=2; i<=num; i++) if(X[ep]!=X[i]) X[++ep]=X[i]; memset(color,0,sizeof(color)); memset(flag,-1,sizeof(flag)); for(int i=0; i<n; i++) { int lx=find(line[i].lx,ep); int rx=find(line[i].rx,ep); Update(1,1,ep+1,lx,rx,line[i].s); } Query(1,1,ep+1); int s=0, d=0, ts, td; for(int i=1; i<=ep; i++) { if(color[i]!=1) continue; ts=X[i]; while(color[i]==1) i++; if(i>ep) break; td=X[i]; if(td-ts>d-s) { s=ts; d=td; } } if(s==d) puts("Oh, my god"); else printf("%d %d\n",s, d-1); } return 0; }
相关文章推荐
- HDU 1199 Color the Ball(离散化入门+非线段树做法)
- SPOJ - WMELON(离散化+暴力or离散化+线段树)【待完善】
- hdu 1199 Color the Ball(离散化线段树)
- Codeforces Round #345 (Div. 1) D. Zip-line 上升子序列 离线 离散化 线段树
- Codeforces 633H. Fibonacci-ish II (Mo's Algorithm(莫队算法) + 线段树 + 离散化)
- 线段树、扫描线、离散化求面积并(hdu1542)
- POJ 2528 Mayor's posters(线段树离散化)
- CodeforcesBeta Round #19 D. Points 离线线段树 单点更新 离散化
- UVa 1471 Defense Lines - 线段树 - 离散化
- hdu4288--Coder--线段树--离线处理+离散化+想法!
- POJ 2528:Mayor's posters(线段树区间更新+离散化)
- 1019.Line Painting(线段树 离散化)
- 中南OJ1551: Longest Increasing Subsequence Again(分块+离散化线段树)
- POJ 2528 Mayor's posters (线段树,染色问题,离散化要注意)
- HDU 1255 覆盖的面积(离散化+线段树)
- caioj【1101】:统计颜色(模板题) 线段树(lazytag)+离散化
- POJ2528:Mayor's posters(线段树区间更新+离散化)
- poj 2528 Mayor's posters(线段树+离散化)
- 2015 UESTC 数据结构专题A题 秋实大哥与小朋友 线段树 区间更新,单点查询,离散化
- poj-3277-City Horizon-离散化+线段树区域更新