传送门: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的更多相关文章

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

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

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

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

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

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

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

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

  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 (离散化+扫描线+树状数组)

    题意:给你若干个平行于坐标轴的,长度大于0的线段,且任意两个线段没有公共点,不会重合覆盖.问有多少个交点. 析:题意很明确,可是并不好做,可以先把平行与x轴和y轴的分开,然后把平行y轴的按y坐标从小到 ...

  7. HDU 5862(离散化+树状数组)

    Problem Counting Intersections 题目大意 给定n条水平或竖直的线段,统计所有线段的交点个数. (n<=100000) 解题分析 首先将线段离散化. 然后将所有线段按 ...

  8. Counting Intersections

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

  9. [hdu 6184 Counting Stars(三元环计数)

    hdu 6184 Counting Stars(三元环计数) 题意: 给一张n个点m条边的无向图,问有多少个\(A-structure\) 其中\(A-structure\)满足\(V=(A,B,C, ...

随机推荐

  1. Titanium开发环境搭建第一个坑

    操作系统: Ubuntu 12.04 LTS AMD64 在Titanium Studio中,装Titanium CLI怎么都不能成功,到了一个进度,发现卡在那里,硬盘一直狂闪,发现在Studio的文 ...

  2. POJ 3233 Matrix Power Series 矩阵快速幂+二分求和

    矩阵快速幂,请参照模板 http://www.cnblogs.com/pach/p/5978475.html 直接sum=A+A2+A3...+Ak这样累加肯定会超时,但是 sum=A+A2+...+ ...

  3. Linux命令详解之—cat命令

    cat命令的功能是连接文件或标准输入并打印,今天就为大家介绍下Linux中的cat命令. 更多Linux命令详情请看:Linux命令速查手册 Linux 的cat命令通常用来显示文件内容,也可以用来将 ...

  4. Java调用JavaScript

    1.main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a ...

  5. SharpGL学习笔记(十三) 光源例子:环绕二次曲面球体的光源

    这是根据徐明亮<OpenGL游戏编程>书上光灯一节的一个例子改编的. 从这个例子可以学习到二次曲面的参数设置,程序中提供了两个画球的函数,一个是用三角形画出来的,一个是二次曲面构成的. 你 ...

  6. 【GOF23设计模式】模板方法模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_模板方法模式.钩子函数.方法回调.好莱坞原则 package com.test.templateMethod; publi ...

  7. Vue表单

    gitHub地址: https://github.com/lily1010/vue_learn/tree/master/lesson11 一 vue表单 实在是太简单了,直接来个例子 <!DOC ...

  8. SeismicPro地震剖面显示程序

    SeismicPro是一个地震剖面显示软件,可从标准SEGY地震数据体中抽取纵测线和横测线的二维剖面,并以波形.变面积和变密度等多种方式进行专业化显示,可进行一键式显示方式切换,并可进行定制开发叠加井 ...

  9. 高级iOS面试题

    非标准答案 2 1: 类方法是可以直接通过类名直接调用,无需进行实例化对象.类方法是以+开头2. 实例方法,需要显示实例化对象,为对象分配堆栈空间,并通过对象实例调用实例方法3. RUNTIME 是在 ...

  10. IOS 友盟使用详解

    IOS 友盟使用详解 这篇博客将会详细介绍友盟的使用,希望对博友们有所帮助. 首先我们在浏览器上搜索友盟. 在这里我们选择官网这个,进去友盟官网后我们按照下图进行选择. 接下来选择如下图 Next 这 ...