POJ 1436 (线段树 区间染色) Horizontally Visible Segments
这道题做了快两天了。首先就是按照这些竖直线段的横坐标进行从左到右排序。
将线段的端点投影到y轴上,线段树所维护的信息就是y轴区间内被哪条线段所覆盖。
对于一条线段来说,先查询和它能相连的所有线段,并加入到一个有向图里面,一遍后面O(n3)暴力统计答案。
然后就是update,用这个线段将对应的区间“染色”
还要注意一个情况就是:
0 3 1, 0 1 2, 2 3 2, 0 3 3折四条线段
| | |
| |
| | |
很明显第一和第三条线段是可相连的,但是中间两条会覆盖掉左边的线段,根据以往的经验,之间将所有纵坐标乘二就好啦。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + ;
int setv[maxn << ];
bool G[maxn][maxn]; int n, qL, qR, v; struct Segment
{
int y1, y2, x;
Segment() {}
Segment(int y1, int y2, int x):y1(y1), y2(y2), x(x) {}
bool operator < (const Segment& rhs) const
{ return x < rhs.x; }
}seg[maxn]; void pushdowm(int o)
{
if(setv[o])
{
setv[o*] = setv[o*+] = setv[o];
setv[o] = ;
}
} void update(int o, int L, int R)
{
if(qL <= L && qR >= R) { setv[o] = v; return; }
pushdowm(o);
int M = (L + R) / ;
if(qL <= M) update(o*, L, M);
if(qR > M) update(o*+, M+, R);
} void query(int o, int L, int R)
{
if(setv[o]) { G[v][setv[o]] = true; return; }
if(L == R) return;
int M = (L + R) / ;
if(qL <= M) query(o*, L, M);
if(qR > M) query(o*+, M+, R);
} int main()
{
//freopen("in.txt", "r", stdin); int T; scanf("%d", &T);
while(T--)
{
memset(setv, , sizeof(setv));
memset(G, false, sizeof(G)); scanf("%d", &n);
for(int i = ; i <= n; i++) scanf("%d%d%d", &seg[i].y1, &seg[i].y2, &seg[i].x);
sort(seg + , seg + + n);
for(int i = ; i <= n; i++)
{
qL = seg[i].y1 * ; qR = seg[i].y2 * ;
v = i;
query(, , maxn * );
update(, , maxn * );
} int ans = ;
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++) if(G[i][j])
for(int k = ; k <= n; k++) if(G[i][k] && G[j][k]) ans++;
printf("%d\n", ans);
} return ;
}
代码君
POJ 1436 (线段树 区间染色) Horizontally Visible Segments的更多相关文章
- HDU3974 Assign the task(多叉树转换为线段+线段树区间染色)
题目大意:有n个人,给你他们的关系(老板和员工),没有直属上司的人就是整个公司的领导者,这意味着n个人形成一棵树(多叉树).当一个人被分配工作时他会让他的下属也做同样的工作(并且立即停止手头正在做的工 ...
- hdu 5023(线段树区间染色,统计区间内颜色个数)
题目描述:区间染色问题,统计给定区间内有多少种颜色? 线段树模板的核心是对标记的处理 可以记下沿途经过的标记,到达目的节点之后一块算,也可以更新的时候直接更新到每一个节点 Lazy操作减少修改的次数( ...
- 线段树区间染色 ZOJ 1610
Count the Colors ZOJ - 1610 传送门 线段树区间染色求染色的片段数 #include <cstdio> #include <iostream> #in ...
- poj 2528 线段树区间修改+离散化
Mayor's posters POJ 2528 传送门 线段树区间修改加离散化 #include <cstdio> #include <iostream> #include ...
- POJ 3667 线段树区间合并
http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html 用线段树,首先要定义好线段树的节点信息,一般看到一个问题,很难很 ...
- Mayor's posters POJ - 2528 线段树区间覆盖
//线段树区间覆盖 #include<cstdio> #include<cstring> #include<iostream> #include<algori ...
- hdu 1698+poj 3468 (线段树 区间更新)
http://acm.hdu.edu.cn/showproblem.php?pid=1698 这个题意翻译起来有点猥琐啊,还是和谐一点吧 和涂颜色差不多,区间初始都为1,然后操作都是将x到y改为z,注 ...
- poj 3468 线段树区间更新/查询
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...
- POJ 3468 (线段树 区间增减) A Simple Problem with Integers
这题WA了好久,一直以为是lld和I64d的问题,后来发现是自己的pushdown函数写错了,说到底还是因为自己对线段树理解得不好. 因为是懒惰标记,所以只有在区间分开的时候才会将标记往下传递.更新和 ...
随机推荐
- CodeForces 321A
A. Ciel and Robot time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- Sqli-labs less 22
Less-22 本关和less20.less21是一致的,我们可以从源代码中看到这里对uname进行了"uname"的处理,可以构造payload: admin1"and ...
- 本地安装xssing
本地安装xssing 环境为apache+mysql+php,linux下和Windows均进行了尝试. 步骤: (1)Mysql中创建xing数据库,将xssing.sql中的语句复制并在xing数 ...
- CentOS 6下安装nginx
原文:http://yubosun.akhtm.com/tech/centos-nginx.htm 1 在nginx官方网站下载一个rpm包,下载地址是:http://nginx.org/en/dow ...
- ZOJ3238 Water Ring(计算几何)
题意:给你一个圆形和很多个矩形,然后要你求圆形的圆周有多少被矩形覆盖. 思路:比赛的时候是有思路的了,不过一直在调别的题,最后剩下30分钟肯定来不及敲.想法是这样的,要是我们可以求出每个矩形覆盖了圆周 ...
- poj 1986
Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 8638 Accepted: 3032 ...
- NSArray block用法
28.使用block 块遍历整个数组.这个block 需要三个参数,id obj 表示数组中的元素. NSUInteger idx 标示元素的下标, bool *stop 是一个bool类型的参数. ...
- Android Drawable体系
- 简单Ajax例子
一.概述 1.程序执行流程: (1)点击id="testBtn"的按钮,触发validate(); (2)validate()中有调用request.open方法与server交互 ...
- 弹性ScrollView,和下啦刷新的效果类似 实现下拉弹回和上拉弹回
今天做了一个弹性ScrollView,和下啦刷新的效果类似,我想这个很多需求都用的这种效果 其实这是一个自定义的scrollView,上代码,这是我写在一个公共的组件包里的 package com.p ...