hdu 5862 Counting Intersections
传送门:hdu 5862 Counting Intersections
题意:对于平行于坐标轴的n条线段,求两两相交的线段对有多少个,包括十,T型
官方题解:由于数据限制,只有竖向与横向的线段才会产生交点,所以先对横向线段按x端点排序,每次加入一个线段,将其对应的y坐标位置+1,当出现一个竖向线段时,查询它的两个y端点之间的和即为交点个数.
注意点:对x坐标排序是对所有线段端点排序;因为可能出现 “ 1-1 “ 这样的情况,所以对于横着的线段,需要进行首尾x坐标处理;我的方法是对于x坐标,先按大小排序,如果大小相同,按先横后竖的方式排序,那么对于 “ 1- ”这样的情况,是能够正确计算的,对于“ -1” 这样的情况,就得对横着的线段的右端点+1处理
总结:这类题型非常常见,处理方法也很巧妙,有必要熟练运用。2016百度之星复赛的1003 拍照 也是同类型的题
/**************************************************************
Problem:hdu 5862 Counting Intersections
User: youmi
Language: C++
Result: Accepted
Time:2199MS
Memory:9124K
****************************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep(i,from,to) for(int i=from;i<=to;i++)
#define irep(i,to,from) for(int i=to;i>=from;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl
const double pi=*atan(1.0); using namespace std;
typedef long long ll;
template <class T> inline void read(T &n)
{
char c; int flag = ;
for (c = getchar(); !(c >= '' && c <= '' || c == '-'); c = getchar()); if (c == '-') flag = -, n = ; else n = c - '';
for (c = getchar(); c >= '' && c <= ''; c = getchar()) n = n * + c - ''; n *= flag;
}
ll Pow(ll base, ll n, ll mo)
{
if (n == ) return ;
if (n == ) return base % mo;
ll tmp = Pow(base, n >> , mo);
tmp = (ll)tmp * tmp % mo;
if (n & ) tmp = (ll)tmp * base % mo;
return tmp;
}
//*************************** int n;
const int maxn=+;
const ll mod=; typedef struct Point
{
int x,y;
int id;
Point(){};
Point(int _x,int _y,int _id)
{
x=_x,y=_y,id=_id;
}
}point;
typedef struct Line
{
point s,e;
int dir;
Line(){};
Line(point _s,point _e,int _dir)
{
s=_s,e=_e,dir=_dir;
}
}line;
line ln[maxn];
point p[maxn<<];
int y[maxn<<];
bool vis[maxn];
bool cmp(point a,point b)
{
return a.x==b.x?ln[a.id].dir<ln[b.id].dir:a.x<b.x;
}
ll c[maxn<<];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int val)
{
while(x<=*n)
{
c[x]+=val;
x+=lowbit(x);
}
}
ll query(int x)
{
ll res=;
while(x)
{
res+=c[x];
x-=lowbit(x);
}
return res;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int T_T;
scanf("%d",&T_T);
for(int kase=;kase<=T_T;kase++)
{
sc(n);
int x1,y1,x2,y2;
rep(i,,n)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(y1>y2||x1>x2)
{
swap(y1,y2);
swap(x1,x2);
}
p[i*-]=Point(x1,y1,i);
p[i*]=Point(x2,y2,i);
y[i*-]=y1,y[i*]=y2;
if(y1==y2)
ln[i]=Line(Point(x1,y1,i),Point(x2,y2,i),),p[i*].x++;//横线的右端点+1
else if(x1==x2)
ln[i]=Line(Point(x1,y1,i),Point(x2,y2,i),);
}
sort(p+,p++*n,cmp);
sort(y+,y++*n);
int k=unique(y+,y++*n)-(y+);
rep(i,,*n)
p[i].y=lower_bound(y+,y++k,p[i].y)-(y);
rep(i,,n)
ln[i].s.y=lower_bound(y+,y++k,ln[i].s.y)-(y),ln[i].e.y=lower_bound(y+,y++k,ln[i].e.y)-(y);
ll ans=;
zeros(c);
zeros(vis);
rep(i,,*n)
{
int dir=ln[p[i].id].dir;
if(dir==)
{
if(vis[p[i].id])
update(p[i].y,-);
else
{
vis[p[i].id]=;
update(p[i].y,);
}
}
else
{
if(vis[p[i].id])
continue;
vis[p[i].id]=;
ll temp=query(ln[p[i].id].e.y);
temp-=query(ln[p[i].id].s.y-);
ans+=temp;
}
}
ptlld(ans);
}
}
hdu 5862 Counting Intersections的更多相关文章
- HDU 5862 Counting Intersections(离散化+树状数组)
HDU 5862 Counting Intersections(离散化+树状数组) 题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 D ...
- Hdu 5862 Counting Intersections(有n条线段,每一条线段都是平行于x轴或者y轴,问有多少个交点+树状数组区间求和单点跟新)
传送门:Hdu 5862 Counting Intersections 题意:有n条线段,每一条线段都是平行于x轴或者y轴,问有多少个交点 分析: 基本的操作流程是:先将所有的线段按照横树坐标x按小的 ...
- HDU 5862 Counting Intersections 扫描线+树状数组
题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 Counting Intersections Time Limit: 12000/ ...
- HDU 5862 Counting Intersections (树状数组)
Counting Intersections 题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 Description Given ...
- HDU 5862 Counting Intersections(离散化 + 树状数组)
Counting Intersections Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- HDU 5862 Counting Intersections (离散化+扫描线+树状数组)
题意:给你若干个平行于坐标轴的,长度大于0的线段,且任意两个线段没有公共点,不会重合覆盖.问有多少个交点. 析:题意很明确,可是并不好做,可以先把平行与x轴和y轴的分开,然后把平行y轴的按y坐标从小到 ...
- HDU 5862(离散化+树状数组)
Problem Counting Intersections 题目大意 给定n条水平或竖直的线段,统计所有线段的交点个数. (n<=100000) 解题分析 首先将线段离散化. 然后将所有线段按 ...
- Counting Intersections
Counting Intersections Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- [hdu 6184 Counting Stars(三元环计数)
hdu 6184 Counting Stars(三元环计数) 题意: 给一张n个点m条边的无向图,问有多少个\(A-structure\) 其中\(A-structure\)满足\(V=(A,B,C, ...
随机推荐
- CentOS 7.2 搭建 Openvpn 服务器
本文将以目前最新的openvpn-2.3.13.tar.gz为例来介绍如何在Linux系统中安装.配置及使用OpenVPN. 在这里,我们选用了一台预装CentOS 7.2 64位系统的计算机作为Op ...
- iOS 线程相关-----绝对de干货
平时用线程总是知其然,而不知所以然,现在针对涉及到的有关线程的知识体系做了一个系统的整理,由于GCD平时用的也比较多,所以用了大量的空间来讲述这一块,其他的涉及的不是很多,也做了说明,真真切切的是一个 ...
- 关于谷歌浏览器不能播放背景音乐的问题(与IE的不同之处)
第一篇博文 忍受寂寞,抵制诱惑,持之以恒. 开发时,以下代码在IE浏览器上能顺利播放背景音乐,可在谷歌浏览器上却没有动静. <html> <body> <bgsound ...
- JSP利用freemarker生成基于word模板的word文档
利用freemarker生成基于word模板的word文档 freemarker简介 FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出.FreeMarker与Web容器 ...
- I/O之输出流 OutputStream类
java的I/O技术可以将数据保存到文本.二进制.ZIP压缩文件中,下面来说说一些基本的常识(今天只讲理论).先来说说流,何为流?“流就是一组有 序的数据序列,根据操作的类型,可以分为输入(Input ...
- C标准库<ctype.h>实现
本文地址:http://www.cnblogs.com/archimedes/p/c-library-ctype.html,转载请注明源地址. 1.背景知识 ctype.h是C标准函数库中的头文件,定 ...
- Fragment官方解析
由于fragment和activity的生命周期很类似,对activity不熟悉的可以参考–深入了解Activity-生命周期, 深入理解Activity-任务,回退栈,启动模式, 概要 A Frag ...
- 用二进制大对象类型Blob实现图片入库与出库的操作
package readclobDemo.bao; import java.io.FileInputStream; import java.io.FileNotFoundException; impo ...
- CSS 子选择器(六)
一.子选择器 子选择器中前后部分之间用一个大于号隔开,前后两部分选择符在结构上属于父子关系. 子选择器是根据左侧选择符指定的父元素,然后在该父元素下寻找匹配右侧选择符的子元素. 二.简单例子 < ...
- Android网络编程基础
Android网络编程只TCP通信 TCP 服务器端工作的主要步骤如下.步骤1 调用ServerSocket(int port)创建一个ServerSocket,并绑定到指定端口上.步骤2 调用acc ...