poj1436(线段树成段更新)
来源:互联网 发布:中国国家图书馆数据 编辑:程序博客网 时间:2024/05/14 04:17
题目链接:poj1436
/*poj1436成段更新(难点:端点的处理)题意: n条竖直线段,每行输入y1,y2,x,分别表示线段下端点,上端点,横坐标定义两天线段可见:如果一条水平线段连接它们,且在它们之间不经过其它线段。最后求有多少组3条线段是两两可见的。思路:首先将所有线段按x坐标的大小进行排序,然后对y轴建树对每一条线段执行查询操作,查询当前线段区间内可见线段有哪些,并记录,然后更新 题目给的是线段的端点,不能直接用区间建树,样例0 3 1,3 4 2,两线段端点在一条水平线上区间建树无法判断此类情况 将纵坐标全部乘以2,就可以处理端点的问题0,4,1 和 0,2,2 和 3,4,2这三条线段覆盖的结果是区间0~4通过线段树查找可见线段是两条,其实是3条(2~3可见另一条)*/#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;#define lson rt<<1#define rson rt<<1|1const int N = 16010;bool v[8005][8005];//v[i][j]表示第i个线段和第j个线段是可见的struct seg{ int x,y1,y2; seg(){} seg(int xx, int yy1, int yy2):x(xx),y1(yy1),y2(yy2){} bool operator < (const seg &cmp) const{ return x < cmp.x; }}ss[N>>1];struct node{ int l,r,c;}s[N<<2];void build(int l, int r, int rt){ s[rt].l = l; s[rt].r = r; s[rt].c = -1; if(l == r) return; int mid = (l+r) >> 1; build(l, mid, lson); build(mid+1, r, rson);}void pushdown(int rt){ if(s[rt].c != -1){ s[lson].c = s[rson].c = s[rt].c; s[rt].c = -1; }}void updata(int c, int l, int r, int rt){ if(l <= s[rt].l && s[rt].r <= r){ s[rt].c = c; return; } pushdown(rt); int mid = (s[rt].l + s[rt].r) >> 1; if(l <= mid) updata(c, l, r, lson); if(mid < r) updata(c, l ,r, rson);}void query(int id, int l, int r, int rt){ if(s[rt].c != -1){ v[id][s[rt].c] = true; return; } if(s[rt].l == s[rt].r) return; int mid = (s[rt].l + s[rt].r) >> 1; if(l <= mid) query(id, l, r, lson); if(mid < r) query(id, l, r, rson);}int main(){ int T,n,i,j,k; scanf("%d",&T); while(T--) { scanf("%d",&n); build(0, N, 1); memset(v, false, sizeof(v)); for(i = 0; i < n; i ++){ int x,y1,y2; scanf("%d%d%d",&y1,&y2,&x); ss[i] = seg(x, y1<<1, y2<<1); } sort(ss, ss+n); for(i = 0; i < n;i ++){ query(i, ss[i].y1, ss[i].y2, 1); updata(i, ss[i].y1, ss[i].y2, 1); } int ans = 0; for(i = 0; i < n; i ++){//暴力枚举 for(j = 0; j < n; j ++){ if(v[i][j]) for(k = 0; k < n; k ++) if(v[i][k] && v[j][k]) ans ++; } } printf("%d\n",ans); } return 0;}
0 0
- poj1436(线段树成段更新)
- poj1436之线段树成段更新
- poj1436 Horizontally Visible Segments 线段树成段更新
- POJ1436 Horizontally Visible Segments 线段树区间更新--区间覆盖
- 【POJ1436】Horizontally Visible Segments-线段树区间更新
- poj1436 线段树+暴力
- 线段树+拆点poj1436
- poj1436(线段树区间染色)
- poj1436 Horizontally Visible Segments 线段树
- poj1436(线段树lazy标记)
- POJ1436:Horizontally Visible Segments(区间更新)
- hdu4027 线段树成段更新
- poj3468 线段树成段更新
- 线段树成段更新-MB
- 线段树成段更新
- poj3468(线段树成段更新)
- hdu1689(线段树成段更新)
- hdu_1698线段树成段更新
- ArcGIS Flex API 拖拽Graphic
- Python环境搭建
- Bloom Filter概念和原理
- Pointcut 切点
- Ubuntu下方便使用的下载工具
- poj1436(线段树成段更新)
- 基于 Distcc 的android分布式编译环境的搭建
- NSRunLoop
- VC CMarkup详细使用方法:
- Java Web 高性能开发,第 2 部分: 前端的高性能
- Oracle 11g 新特性——I/O校准
- 网站建设需要注意哪些问题
- 进程和线程的联系和区别
- Java Web 高性能开发,第 1 部分: 前端的高性能