poj 1436 成段更新(区间覆盖)
来源:互联网 发布:飞机销售网软件 编辑:程序博客网 时间:2024/05/29 14:43
Horizontally Visible Segments
Time Limit: 5000MS Memory Limit: 65536KTotal Submissions: 2578 Accepted: 965
Description
There is a number of disjoint vertical line segments in the plane. We say that two segments are horizontally visible if they can be connected by a horizontal line segment that does not have any common points with other vertical segments. Three different vertical segments are said to form a triangle of segments if each two of them are horizontally visible. How many triangles can be found in a given set of vertical segments?
Task
Write a program which for each data set:
reads the description of a set of vertical segments,
computes the number of triangles in this set,
writes the result.
Task
Write a program which for each data set:
reads the description of a set of vertical segments,
computes the number of triangles in this set,
writes the result.
Input
The first line of the input contains exactly one positive integer d equal to the number of data sets, 1 <= d <= 20. The data sets follow.
The first line of each data set contains exactly one integer n, 1 <= n <= 8 000, equal to the number of vertical line segments.
Each of the following n lines consists of exactly 3 nonnegative integers separated by single spaces:
yi', yi'', xi - y-coordinate of the beginning of a segment, y-coordinate of its end and its x-coordinate, respectively. The coordinates satisfy 0 <= yi' < yi'' <= 8 000, 0 <= xi <= 8 000. The segments are disjoint.
The first line of each data set contains exactly one integer n, 1 <= n <= 8 000, equal to the number of vertical line segments.
Each of the following n lines consists of exactly 3 nonnegative integers separated by single spaces:
yi', yi'', xi - y-coordinate of the beginning of a segment, y-coordinate of its end and its x-coordinate, respectively. The coordinates satisfy 0 <= yi' < yi'' <= 8 000, 0 <= xi <= 8 000. The segments are disjoint.
Output
The output should consist of exactly d lines, one line for each data set. Line i should contain exactly one integer equal to the number of triangles in the i-th data set.
Sample Input
150 4 40 3 13 4 20 2 20 2 3
Sample Output
1传送门:http://blog.csdn.net/zxy_snow/article/details/6829766
http://www.cnblogs.com/wuyiqi/archive/2012/02/02/2336350.html
http://blog.csdn.net/qingniaofy/article/details/7772293
注意:如 样例 中 ,0 2 2,3 4 2这两条线段,可以看到 2 3之间是没有被覆盖的,但是在线段树中我们看不到这条线段,因为 变成 浮点数了,不能处理,那么我们可以将 坐标 x2,这样就变成 4 6,中间就多出一个点 5 了,就可以判断了。。
下面这个图是我徒手画的,很丑吧,嘻嘻。。表示了偶数点代表点,奇数代表线段,遇到有线段类的题目(用线段树做)经常要考虑乘以2,表示浮点的线段。。。poj 3225这题类似
#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#define FOR(i,s,t) for(int i=(s); i<(t); i++)using namespace std;const int maxn = 20000;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1struct v_seg{ int s,t; int x;}ss[maxn];int cover[maxn<<2];int Hash[maxn];vector<int> V[maxn];void pushdown(int rt){ if(cover[rt]!=-1){ cover[rt<<1]=cover[rt<<1|1]=cover[rt]; cover[rt]=-1; }}void update(int L,int R,int id,int l,int r,int rt){ if(L<=l&&r<=R){ cover[rt]=id; return ; } pushdown(rt); int m=(l+r)>>1; if(L<=m) update(L,R,id,lson); if(R>m) update(L,R,id,rson);}void query(int L,int R,int id,int l,int r,int rt){ if(cover[rt]!=-1){ if(Hash[cover[rt]]!=id){ V[cover[rt]].push_back(id); Hash[cover[rt]]=id; } return ; } if(l==r) return ; pushdown(rt); int m=(l+r)>>1; if(L<=m) query(L,R,id,lson); if(R>m) query(L,R,id,rson);}int cmp(v_seg a,v_seg b){ return a.x<b.x;}int main(){ int t,i,j,k,n,T,h; scanf("%d",&T); while(T--){ memset(cover,-1,sizeof(cover)); memset(Hash,-1,sizeof(Hash)); scanf("%d",&n); for(i=0;i<n;i++){ scanf("%d%d%d",&ss[i].s,&ss[i].t,&ss[i].x); ss[i].s<<=1;ss[i].t<<=1;V[i].clear(); } sort(ss,ss+n,cmp); for(i=0;i<n;i++){ query(ss[i].s,ss[i].t,i,0,16000,1); update(ss[i].s,ss[i].t,i,0,16000,1); } FOR(i, 0, n){sort(V[i].begin(), V[i].end());} int ans=0; FOR(i, 0, n){int len = V[i].size();FOR(k, 0, len){FOR(j, k+1, len) // 经测试,根据POJ的数据,最内层这个计算量不到50w{int a = V[i][k];int b = V[i][j];if( binary_search(V[a].begin(), V[a].end(), b) )ans++;}}} printf("%d\n",ans); } return 0;}
- poj 1436 成段更新(区间覆盖)
- POJ 3667 Hotel(成段更新,区间合并)
- Poj 3667 Hotel 成段更新,区间合并,区间求和
- POJ 3468 【线段树区间更新-成段更新】
- POJ 3580 SuperMemo(splay成段更新、区间最小值、反转、插入和删除、区间搬移)
- POJ 3667 Hotel 线段树 区间合并(成段更新)
- POJ 3667(线段树,区间合并,成段更新)
- poj 2777 Count Color (成段更新+区间求和)
- poj 3468 线段树 区间内的线段和(成段更新)
- poj 3468 A Simple Problem with Integers(线段树|成段更新,区间查询)
- poj 4047 Garden 2012金华赛区 (成段更新+区间最值)
- Poj 1823 Hotel (线段树 区间合并 成段更新)
- POJ 3468-A Simple Problem with Integers(线段树:成段更新,区间求和)
- poj(2777)——Count Color(lazy思想,成段更新,区间统计)
- poj 3468__A Simple Problem with Integers(区间求和,成段更新)
- POJ 3468 A Simple Problem with Integers (splay 成段更新、区间求和)
- hdu 3577 线段树,成段更新 好题 查询区间的最大覆盖次数
- 线段树 区间更新(成段更新) HDU1698
- PO BO VO DTO POJO DAO概念及其作用(附转换图)
- 名字空间示例
- Integer.valueOf()和Integer.ParseInt()的区别
- Android 开发之旅:view的几种布局方式及实践
- c++模版特化
- poj 1436 成段更新(区间覆盖)
- 打造最快的Hash表
- Java去掉 URL 中的 jsessionid
- android 各个存储路径的解释
- socks
- 日语的常用副词
- 利用 Console 来学习、调试JavaScrip
- 数据库Oracle/Mysql应用总结
- 日语的常用接续词