博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ-1436 线段树 区间更新
阅读量:6069 次
发布时间:2019-06-20

本文共 2298 字,大约阅读时间需要 7 分钟。

题中定义了什么叫做可见线段。所谓可见线段就是在给定的垂直与x轴的直线中,能够在两个直线之间连接一条平行线,并且这条平行线不与任何其他的直线相交。

WA一次,就是因为没有考虑到在建立点树的过程中会出现将 [1, 2] 和 [3, 4] 视为一条连接的直线,所以最后给坐标乘以一个2.

代码如下:

#include 
#include
#include
#include
#include
#include
#define MAXN 8000 using namespace std; struct Seq { int y1, y2, x; bool operator < (Seq t) const { return x < t.x; } }e[MAXN+5]; struct { int l, r, who; }seg[MAXN*8]; map
m[MAXN+5]; void build(int f, int l, int r) { int mid = l+r >> 1; seg[f].l = l, seg[f].r = r; seg[f].who = 0; if (r > l) { build(f<<1, l, mid); build(f<<1|1, mid+1, r); } } void up(int f) { if (seg[f<<1].who == seg[f<<1|1].who) seg[f].who = seg[f<<1].who; else seg[f].who = -1; } void modify(int f, int l, int r, int who, map
*m) { int mid = seg[f].l+seg[f].r >> 1; if (seg[f].l == l && seg[f].r == r && (seg[f].who != -1 || r==l)) { if (seg[f].who != -1 && seg[f].who != 0) m[who][seg[f].who] = 1; seg[f].who = who; } else if (seg[f].r > seg[f].l) { if (seg[f].who == 0) { seg[f<<1].who = seg[f<<1|1].who = seg[f].who; seg[f].who = -1; } else if (seg[f].who != -1) { m[who][seg[f].who] = 1; seg[f<<1].who = seg[f<<1|1].who = seg[f].who; seg[f].who = -1; } if (r <= mid) modify(f<<1, l, r, who, m); else if (l > mid) modify(f<<1|1, l, r, who, m); else { modify(f<<1, l, mid, who, m); modify(f<<1|1, mid+1, r, who, m); } up(f); } } int main() { map
::iterator it1, it2; int T, M, y1, y2, x, ans; scanf("%d", &T); build(1, 0, 2*MAXN); while (T--) { ans = 0; seg[1].who = 0; scanf("%d", &M); for (int i = 1; i <= M; ++i) { scanf("%d %d %d", &e[i].y1, &e[i].y2, &e[i].x); e[i].y1 <<= 1, e[i].y2 <<= 1; m[i].clear(); } sort(e+1, e+1+M); for (int i = 1; i <= M; ++i) { // printf("%d %d %d\n", e[i].y1, e[i].y2, e[i].x); modify(1, e[i].y1, e[i].y2, i, m); /* for (it = m[i].begin(); it != m[i].end(); ++it) printf(".. %d ", it->first); */ } for(int i = 1; i <= M; ++i) // 扫描整个表 { for(it1 = m[i].begin(); it1 != m[i].end(); ++it1) // 遍历第i条线的可见线段 { int k = it1->first; // 记录与其中的第k条线段可见 for(it2 = m[i].begin(); it2 != m[i].end(); ++it2) // 如果第k条线段与第i条线段有共同的可见线段的话 ans++ { if (m[k].count(it2->first)) ans++; } } } printf("%d\n",ans); } return 0; }

转载于:https://www.cnblogs.com/Lyush/archive/2012/03/08/2385436.html

你可能感兴趣的文章
深入浅出Netty
查看>>
3.使用maven创建java web项目
查看>>
笔记本搜索不到某一AP广播的SSID,信道的原因
查看>>
基于Spring MVC的异常处理及日志管理
查看>>
MediaBrowserService 音乐播放项目《IT蓝豹》
查看>>
MySQL入门12-数据类型
查看>>
Windows Azure 保留已存在的虚拟网络外网IP(云服务)
查看>>
修改字符集
查看>>
HackTheGame 攻略 - 第四关
查看>>
js删除数组元素
查看>>
带空格文件名的处理(find xargs grep ..etc)
查看>>
华为Access、Hybrid和Trunk的区别和设置
查看>>
centos使用docker下安装mysql并配置、nginx
查看>>
关于HTML5的理解
查看>>
需要学的东西
查看>>
Internet Message Access Protocol --- IMAP协议
查看>>
Linux 获取文件夹下的所有文件
查看>>
对 Sea.js 进行配置(一) seajs.config
查看>>
dom4j解析xml文件
查看>>
第六周
查看>>