poj 1436【线段树--lazy,区间与端点,结束与否,时间与投影,访问一次】
2011-09-24 21:06
316 查看
Horizontally Visible Segments
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.
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.
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
Sample Output
Source
Central Europe 2001
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 1472 | Accepted: 540 |
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.
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.
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
1 5 0 4 4 0 3 1 3 4 2 0 2 2 0 2 3
Sample Output
1
Source
Central Europe 2001
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <vector> #include <algorithm> using namespace std; #define MIX -1 #define maxn 8000 struct tnode{ int l, r, c; }tree[maxn*12]; struct segment{ int x,y1,y2; }seg[maxn]; bool cmp(segment a, segment b) { return a.x<b.x; } int v[maxn]; vector<int> see[maxn]; void buildtree(int k, int l, int r) { tree[k].l=l; tree[k].r=r; tree[k].c=MIX; if (l==r) return; int mid=(l+r)>>1; buildtree(k<<1, l, mid); buildtree((k<<1)+1, mid+1, r); } void update(int k, int l, int r, int id) { if (l<=tree[k].l && r>=tree[k].r) { tree[k].c=id; return; } int lson=k<<1, rson=lson+1, mid=(tree[k].l+tree[k].r)>>1; if (tree[k].c!=MIX) { tree[lson].c = tree[rson].c = tree[k].c; tree[k].c=MIX; } if (l<=mid) update(lson, l ,r, id); if (mid<r) update(rson, l, r, id); if (tree[lson].c==tree[rson].c) tree[k].c = tree[lson].c; } void query(int k, int l, int r, int id) { if(l<=tree[k].l&&tree[k].r<=r) { if (tree[k].c!=MIX) { if (v[tree[k].c]!=id) { // cout<<"fuck.."<<' '<<k<<' '<<tree[k].l<<' '<<tree[k].r<<endl; see[tree[k].c].push_back(id); v[tree[k].c]=id; } return; } } if (tree[k].l==tree[k].r) return; int lson=k<<1, rson=lson+1, mid=(tree[k].l+tree[k].r)>>1; if (tree[k].c!=MIX) { tree[lson].c = tree[rson].c = tree[k].c; tree[k].c=MIX; } /* if (r<=mid) query(lson, l, r, id); else if (mid<l) query(rson, l, r, id); else { query(lson, l, mid, id); query(rson, mid+1, r, id); } */ if(l<=mid) query(lson,l,r,id); if(mid<r) query(rson,l,r,id); if (tree[lson].c==tree[rson].c) tree[k].c=tree[lson].c; } void print(int rt) { printf("rt=%d,l=%d,r=%d,c=%d\n",rt,tree[rt].l,tree[rt].r,tree[rt].c); if(tree[rt].l==tree[rt].r) return; print(rt<<1); print(rt<<1|1); } int main() { int cs, n, ans; scanf("%d", &cs); while (cs--) { buildtree(1, 0, 16000); scanf("%d", &n); for (int i=0; i<n; i++) { scanf("%d%d%d", &seg[i].y1, &seg[i].y2, &seg[i].x); seg[i].y1*=2; seg[i].y2*=2; see[i].clear(); } sort(seg, seg+n, cmp); memset(v, 255, sizeof(v)); for (int i=0; i<n; i++) { query(1, seg[i].y1, seg[i].y2, i); /* cout<<"After query:"<<endl; print(1); int j; for(j=0;j<n;j++) { cout<<j<<':'; int k; for(k=0;k<see[j].size();k++) cout<<see[j][k]<<' '; cout<<endl; }*/ update(1, seg[i].y1, seg[i].y2, i); /* cout<<"After update:"<<endl; print(1); for(j=0;j<n;j++) { cout<<j<<':'; int k; for(k=0;k<see[j].size();k++) cout<<see[j][k]<<' '; cout<<endl; } getchar(); */ } ans=0; for (int i=0; i<n; i++) { int si=see[i].size(); for (int j=0; j<si; j++) //i sees see[i][j] for (int k=j+1; k<si; k++) //i sees see[i][k] (promise j<k) { int sj=see[see[i][j]].size(); for (int l=0; l<sj; l++) //check if see[i][j] sees see[i][k] if (see[see[i][j]][l] == see[i][k]) { ans++; break; } } } printf("%d\n",ans); } system("pause"); return 0; }
相关文章推荐
- Count Color+POJ+线段树区间更新+位运算(lazy标志的运用)
- POJ 1436 Horizontally VisibleSegments(线段树:区间覆盖染色)
- poj 3468 线段树区间更新lazy
- poj 1436 Horizontally Visible Segments(线段树基础,区间染色,拆点)
- poj 3468 线段树区间更新lazy
- poj 3225 Help with Intervals 线段树lazy-tag求解区间运算
- 线段树区间更新——POJ 1436
- poj 3468 线段树区间更新lazy
- poj 3468 线段树区间更新lazy
- poj1436(线段树lazy标记)
- poj 1436 线段树区间操作 Horizontally Visible Segments
- poj 3667 Hotel(线段树,成段更新,区间合并,Lazy思想)
- POJ 2528 Mayor's posters 线段树区间更新+端点离散化
- poj 3468 A Simple Problem with Integers (线段树区间更新求和lazy思想)
- POJ 1436 Horizontally Visible Segments(线段树区间更新)
- POJ 3468-A Simple Problem with Integers(线段树_区间更新+lazy标记)
- poj 1436 Horizontally Visible Segments - 线段树区间更新
- POJ 1436 (线段树 区间染色) Horizontally Visible Segments
- poj 1436 区间线段树 离散化
- POJ 1436 Horizontally Visible Segments(线段树区间染色查询)