zoj3299 Fall the Brick map 离散化
2013-05-16 23:52
330 查看
正在缓慢地学习交大的《题目与解读》这本书,里面很多题目都是很有意思的。
zoj3299 Fall the Brick。
给一些条状的方块,和一些水平的board,求每个board上有多少个单位方块。单位方块长度为1,会落在该位置最高的一个board上。
比较直观的是线段树的解法吧。
书里写到了用map的做法。
其实这种离散化后用(l,1),(r,-1)的事件来处理大范围坐标的题目也见过很多次了。不过还是不够熟练,思考、调试了半天。。。
具体的处理方法:
1.将每个条块的变为两个事件(l,0,1)表示加入一个条块,(r,0,-1)表示减去一个条块。将第i个board也变为两个事件(l,i,1)(r,i,-1)。
2.离散化。这里我没有离散化,因为只要从左到右扫一遍,我就直接排序扫过去了。如果两个点的x坐标相同,相减为0,不会造成错误。
3.排序这些事件,从左到右处理:
用tcnt计数,记录前一个区段有几个条块。用pre保存这个区段的起点。
对于每个事件,先处理这个事件之前的区间,总单位方块数量就是条块的数量乘以区间长度,用map找到之前区间中最高的一个board,将这些方块加入该board中。
然后处理这个事件。条块是1就将tcnt++,-1就tcnt--。如果是board,就在map中加入或删除该board。
4.然后输出答案啦。
这种离散化的问题和这种处理方法还需要多加练习,否则碰到陌生的问题很难想清楚,还有速度,速度。
zoj3299 Fall the Brick。
给一些条状的方块,和一些水平的board,求每个board上有多少个单位方块。单位方块长度为1,会落在该位置最高的一个board上。
比较直观的是线段树的解法吧。
书里写到了用map的做法。
其实这种离散化后用(l,1),(r,-1)的事件来处理大范围坐标的题目也见过很多次了。不过还是不够熟练,思考、调试了半天。。。
具体的处理方法:
1.将每个条块的变为两个事件(l,0,1)表示加入一个条块,(r,0,-1)表示减去一个条块。将第i个board也变为两个事件(l,i,1)(r,i,-1)。
2.离散化。这里我没有离散化,因为只要从左到右扫一遍,我就直接排序扫过去了。如果两个点的x坐标相同,相减为0,不会造成错误。
3.排序这些事件,从左到右处理:
用tcnt计数,记录前一个区段有几个条块。用pre保存这个区段的起点。
对于每个事件,先处理这个事件之前的区间,总单位方块数量就是条块的数量乘以区间长度,用map找到之前区间中最高的一个board,将这些方块加入该board中。
然后处理这个事件。条块是1就将tcnt++,-1就tcnt--。如果是board,就在map中加入或删除该board。
4.然后输出答案啦。
这种离散化的问题和这种处理方法还需要多加练习,否则碰到陌生的问题很难想清楚,还有速度,速度。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> using namespace std; #define NN 401000 int n,m; struct bar{ int h,l,r; long long c; }c[NN]; struct node{ int l,v,c; void init(int a,int b,int cc){l=a;v=b;c=cc;} }sx[NN],tn; bool cmp(node a,node b){ if (a.l==b.l) return a.c<b.c; return a.l<b.l; } map<int,int> mp; void work(int tx){ mp.clear(); int i,j,tcnt=0,pre=sx[1].l; int tmp; for(i=1;i<=tx;++i){ if (mp.rbegin()!=mp.rend()){ tmp=mp.rbegin()->second; c[tmp].c+=((long long)sx[i].l-pre)*tcnt; } if (sx[i].v>0){ if (sx[i].c==1) mp[c[sx[i].v].h]=sx[i].v; else mp.erase(c[sx[i].v].h); } else{ if (sx[i].c==1) tcnt+=1; else tcnt-=1; } pre=sx[i].l; } } int main(){ int tx,i,lb,rb; while(scanf("%d%d",&n,&m)!=EOF){ tx=0; for(i=1;i<=n;++i){ scanf("%d%d",&lb,&rb); tn.init(lb,0,1); sx[++tx]=tn; tn.init(rb,0,-1); sx[++tx]=tn; } for(i=1;i<=m;++i){ scanf("%d%d%d",&c[i].l,&c[i].r,&c[i].h); c[i].c=0; tn.init(c[i].l,i,1); sx[++tx]=tn; tn.init(c[i].r,i,-1); sx[++tx]=tn; } sort(sx+1,sx+tx+1,cmp); work(tx); for(i=1;i<=m;++i){ printf("%lld\n",c[i].c); } printf("\n"); } return 0; }
相关文章推荐
- ZOJ 3299-Fall the Brick(线段树+离散化)
- zoj 3299 Fall the Brick 离散化+区间更新+区间查询
- zoj 3299 Fall the Brick
- ZOJ 3299 Fall the Brick (线段树)
- 【ZOJ】3299 Fall the Brick 线段树
- ZOJ 3299 Fall the Brick(线段树区间更新)
- zoj 3299 Fall the Brick
- ZOJ 3299 Fall the Brick(成段更新)
- ZOJ 2104/HDU 1004 Let the Balloon Rise(map容器)
- zoj_3674_Search in the Wiki(map)
- ZOJ 3674 Search in the Wiki(字典树 + map + vector)
- zoj 2301 Color the Ball(区间染色,线段树+离散化)
- ZOJ 1610 Count the Colors(线段覆盖着色:离散化)
- ZOJ 3674 Search in the Wiki 字典树+set+map映射
- 线段树区间更新+离散化——ZOJ 3299
- zoj 3299(区间改动+离散化)
- ZOJ 1853 || HOJ 1388 The Brick Stops Here
- zoj 3299 线段树 离散化
- zoj3299 Fall the Brick
- zoj 3299(区间修改+离散化)