Counting Intersections

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Problem Description
Given some segments which are paralleled to the coordinate axis. You need to count the number of their intersection.

The input data guarantee that no two segments share the same endpoint, no covered segments, and no segments with length 0.

 
Input
The first line contains an integer T, indicates the number of test case.

The
first line of each test case contains a number n(1<=n<=100000),
the number of segments. Next n lines, each with for integers, x1, y1,
x2, y2, means the two endpoints of a segment. The absolute value of the
coordinate is no larger than 1e9.

 
Output
For each test case, output one line, the number of intersection.
 
Sample Input
2
4
1 0 1 3
2 0 2 3
0 1 3 1
0 2 3 2
4
0 0 2 0
3 0 3 2
3 3 1 3
0 3 0 2
 
Sample Output
4
0
分析:对于横向线段只保留两个端点并记录类型,对竖向线段保留整个线段;
   离散化并排序,遍历竖向线段,对横向端点树状数组更新;
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, rt<<1
#define Rson mid+1, R, rt<<1|1
const int maxn=2e5+;
const int dis[][]={{,},{-,},{,-},{,}};
using namespace std;
ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=;while(q){if(q&)f=f*p;p=p*p;q>>=;}return f;}
int n,m,k,t,x[maxn],y[maxn],p[maxn],xcnt,ycnt,id,idx;
ll ans;
multiset<int>s;
struct node
{
int x,low,high;
bool operator<(const node&p)const
{
return x<p.x;
}
}a[maxn];
struct node1
{
int x,y,type;
bool operator<(const node1&p)const
{
return x<p.x;
}
}g[maxn];
int get(int x)
{
int sum=;
for(int i=x;i;i-=(i&(-i)))
sum+=p[i];
return sum;
}
void add(int x,int y)
{
for(int i=x;i<=maxn-;i+=(i&(-i)))
p[i]+=y;
}
int main()
{
int i,j;
scanf("%d",&t);
while(t--)
{
xcnt=ycnt=id=idx=;
ans=;
memset(p,,sizeof(p));
scanf("%d",&n);
rep(i,,n)
{
int b,c,d,e;
scanf("%d%d%d%d",&b,&c,&d,&e);
if(c>e)swap(c,e);
if(b>d)swap(b,d);
if(b==d)
{
x[++xcnt]=a[++id].x=b;
y[++ycnt]=a[id].low=c;
y[++ycnt]=a[id].high=e;
}
else
{
x[++xcnt]=b;
x[++xcnt]=d;
y[++ycnt]=c;
g[++idx].x=b;
g[idx].y=c;
g[idx].type=;
g[++idx].x=d;
g[idx].y=e;
g[idx].type=;
}
}
sort(x+,x+xcnt+);
sort(y+,y+ycnt+);
sort(a+,a+id+);
sort(g+,g+idx+);
int num1=unique(x+,x+xcnt+)-x-;
int num2=unique(y+,y+ycnt+)-y-;
rep(i,,id)
{
a[i].x=lower_bound(x+,x+num1+,a[i].x)-x;
a[i].low=lower_bound(y+,y+num2+,a[i].low)-y;
a[i].high=lower_bound(y+,y+num2+,a[i].high)-y;
}
rep(i,,idx)
{
g[i].x=lower_bound(x+,x+num1+,g[i].x)-x;
g[i].y=lower_bound(y+,y+num2+,g[i].y)-y;
}
int now=;
rep(i,,id)
{
while(now<=idx&&g[now].x<=a[i].x)
{
if(g[now].type==)add(g[now].y,);
else {
if(g[now].x!=a[i].x)
add(g[now].y,-);
else s.insert(g[now].y);
}
now++;
}
ans+=get(a[i].high)-get(a[i].low-);
for(int x:s)add(x,-);
s.clear();
}
printf("%lld\n",ans);
}
//system("Pause");
return ;
}

Counting Intersections的更多相关文章

  1. hdu 5862 Counting Intersections

    传送门:hdu 5862 Counting Intersections 题意:对于平行于坐标轴的n条线段,求两两相交的线段对有多少个,包括十,T型 官方题解:由于数据限制,只有竖向与横向的线段才会产生 ...

  2. HDU 5862 Counting Intersections (树状数组)

    Counting Intersections 题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 Description Given ...

  3. HDU 5862 Counting Intersections(离散化+树状数组)

    HDU 5862 Counting Intersections(离散化+树状数组) 题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 D ...

  4. HDU 5862 Counting Intersections 扫描线+树状数组

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 Counting Intersections Time Limit: 12000/ ...

  5. HDU 5862 Counting Intersections(离散化 + 树状数组)

    Counting Intersections Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  6. Hdu 5862 Counting Intersections(有n条线段,每一条线段都是平行于x轴或者y轴,问有多少个交点+树状数组区间求和单点跟新)

    传送门:Hdu 5862 Counting Intersections 题意:有n条线段,每一条线段都是平行于x轴或者y轴,问有多少个交点 分析: 基本的操作流程是:先将所有的线段按照横树坐标x按小的 ...

  7. hdu-5862 Counting Intersections(线段树+扫描线)

    题目链接: Counting Intersections Time Limit: 12000/6000 MS (Java/Others)     Memory Limit: 65536/65536 K ...

  8. 2016暑假多校联合---Counting Intersections

    原题链接 Problem Description Given some segments which are paralleled to the coordinate axis. You need t ...

  9. 【HDU5862】Counting Intersections

    题意 有n条线段,且都平行于坐标轴.对于每条线段,给出两个端点的坐标.问一共有多少个线段的交点. 分析 最最简单的扫描法了.用线段树或者树状数组都可以. 由题目可知,线段只有两种,要么平行于x轴要么平 ...

随机推荐

  1. Linux系统的信号详解

    一.信号类型 1) SIGHUP       2) SIGINT       3) SIGQUIT     4) SIGILL        5) SIGTRAP 6) SIGABRT      7) ...

  2. perl的package和module

    来源: http://www.cnblogs.com/itech/archive/2010/03/23/1692836.html 一 package 1) package 相当于C++中的namesp ...

  3. E212:无法打开并写入文件

    用vi编辑文件是  老师出现这样的错误 有些文件   需要root权限才能修改   切换成root权限就行了

  4. 诡异的php 输出缓冲

    我的本地环境 windows + apche + php5.2 今天,碰到一个诡异的问题,以前认为  php 脚本中调用 heade()函数之前不能有任何的如 echo,print ,print_r, ...

  5. MYSQL和ORACLE的触发器与存储过程语法差异

    整改了一番脚本,遇到了一些两种数据库之间的差异,记录一下: 触发器: 差异 MYSQL ORACLE 说明 创建语句不同 create trigger `AA` BEFORE INSERT on `B ...

  6. js获取当前日期与星期

    var currentDate = new Date(); var weekday = ["星期日", "星期一", "星期二", &quo ...

  7. Converting between IEEE 754 and Float (Format related

    The float can be converted to well known single-precision IEEE 754 number, why 754? It's the standar ...

  8. ibatis 自动生成map,bean,dao

    1.下载 AbatorForEclipse1.1.0 地址:http://download.csdn.net/detail/fym548/9426877 点击Archive按钮选择下载的,然后重启My ...

  9. xp安装maven

    1.下载apache-maven-2.0.8 2.设置xp环境变量 MAVEN_HOME D:\apache-maven-2.0.8 在path里面假如  %MAVEN_HOME%\bin 然后打开c ...

  10. Flexigrid的API

    基本设定 width  table的长度(default:auto) height  table的宽度(default:200) striped   表格的线的表示(default:true) nov ...