Problem Counting Intersections

题目大意

  给定n条水平或竖直的线段,统计所有线段的交点个数。 (n<=100000)

解题分析

  首先将线段离散化。

  然后将所有线段按照横坐标的顺序,按照先插入再查找再删除的顺序进行操作。

  对于横线 如果是左端点,则将其纵坐标加1,右端点则减1,对于竖线直接求和就行了。

参考程序

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std; #define N 100008
#define M 50008
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define clr(x,v) memset(x,v,sizeof(x));
#define rep(x,y,z) for (int x=y;x<=z;x++)
#define repd(x,y,z) for (int x=y;x>=z;x--)
const int mo = ;
const int inf = 0x3f3f3f3f;
const int INF = ;
/**************************************************************************/
struct line{
int x,y,z;
line(int x=,int y=,int z=):x(x),y(y),z(z){}
bool operator <(const line b) const{
return x<b.x || x==b.x && z<b.z;
}
}a[N],b[N],c[N*]; int val[N*],cnt; int id(int x){
return lower_bound(val+,val+cnt+,x)-val;
} struct Binary_Indexed_Tree{
int a[N*];
void clear(){
clr(a,);
}
void insert(int x,int val){
for (int i=x;i<=N<<;i+=i & (-i))
a[i]+=val;
}
int sigma(int x){
int res=;
for (int i=x;i>;i-=i & (-i))
res+=a[i];
return res;
}
int query(int x,int y){
return sigma(y)-sigma(x-);
}
}T; int main(){
int testcase;
scanf("%d",&testcase);
while (testcase--){
int n,na=,nb=,nc=;
cnt=;
scanf("%d",&n);
rep(i,,n){
int x1,y1,x2,y2;
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
val[++cnt]=x1;
val[++cnt]=y1;
val[++cnt]=x2;
val[++cnt]=y2;
if (x1==x2){
if (y1>y2) swap(y1,y2);
b[++nb]=line(x1,y1,y2);
}
if (y1==y2){
if (x1>x2) swap(x1,x2);
a[++na]=line(y1,x1,x2);
}
}
sort(val+,val+cnt+);
cnt=unique(val+,val+cnt+)-val-;
rep(i,,na){
a[i].x=id(a[i].x);
a[i].y=id(a[i].y);
a[i].z=id(a[i].z);
c[++nc]=line(a[i].y,i,);
c[++nc]=line(a[i].z,i,);
}
rep(i,,nb){
b[i].x=id(b[i].x);
b[i].y=id(b[i].y);
b[i].z=id(b[i].z);
c[++nc]=line(b[i].x,i,);
}
sort(c+,c+nc+);
T.clear();
LL ans=;
rep(i,,nc){
if (c[i].z==){
T.insert(a[c[i].y].x,);
}
if (c[i].z==){
ans+=T.query(b[c[i].y].y,b[c[i].y].z);
}
if (c[i].z==){
T.insert(a[c[i].y].x,-);
}
}
printf("%lld\n",ans );
}
}

  

HDU 5862(离散化+树状数组)的更多相关文章

  1. HDU 4325 离散化+树状数组 或者 不使用树状数组

    题意:给出一些花的开放时间段,然后询问某个时间点有几朵花正在开放. 由于ti<1e9,我们需要先将时间离散化,然后将时间点抽象为一个数组中的点,显然,我们需要进行区间更新和单点查询,可以考虑线段 ...

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

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

  3. hdu 3015 Disharmony Trees (离散化+树状数组)

    Disharmony Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. HDU 6318.Swaps and Inversions-求逆序对-线段树 or 归并排序 or 离散化+树状数组 (2018 Multi-University Training Contest 2 1010)

    6318.Swaps and Inversions 这个题就是找逆序对,然后逆序对数*min(x,y)就可以了. 官方题解:注意到逆序对=交换相邻需要交换的次数,那么输出 逆序对个数 即可. 求逆序对 ...

  5. CodeForces 540E - Infinite Inversions(离散化+树状数组)

    花了近5个小时,改的乱七八糟,终于A了. 一个无限数列,1,2,3,4,...,n....,给n个数对<i,j>把数列的i,j两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树 ...

  6. Ultra-QuickSort(归并排序+离散化树状数组)

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 50517   Accepted: 18534 ...

  7. BZOJ_4627_[BeiJing2016]回转寿司_离散化+树状数组

    BZOJ_4627_[BeiJing2016]回转寿司_离散化+树状数组 Description 酷爱日料的小Z经常光顾学校东门外的回转寿司店.在这里,一盘盘寿司通过传送带依次呈现在小Z眼前.不同的寿 ...

  8. poj-----Ultra-QuickSort(离散化+树状数组)

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 38258   Accepted: 13784 ...

  9. Code Forces 652D Nested Segments(离散化+树状数组)

     Nested Segments time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  10. 【bzoj4627】[BeiJing2016]回转寿司 离散化+树状数组

    题目描述 给出一个长度为n的序列,求所有元素的和在[L,R]范围内的连续子序列的个数. 输入 第一行包含三个整数N,L和R,分别表示寿司盘数,满意度的下限和上限. 第二行包含N个整数Ai,表示小Z对寿 ...

随机推荐

  1. oracle查锁表SQL

    SELECT l.session_id sid, s.serial#, l.locked_mode, l.oracle_username, s.user#, l.os_user_name,s.mach ...

  2. 设置正确的post数据格式

    之前一直使用苏飞的HttpHelper类来访问网络,用起来一直感觉很爽.使用其工具直接生成访问代码很是方便.直到昨天下午做到需要使用wpf来post两个字段数据到服务器,服务器使用ASP.NET MV ...

  3. java 面向对象编程-- 第15章 集合框架

    1.  集合特点:元素类型不同.集合长度可变.空间不固定 2.  java中对一些数据结构和算法进行了封装即集合.集合也是一种对象,用于存储.检索.操作和传输对象. 3.  JCF(Java Coll ...

  4. 转: ORACLE索引介绍和使用

    1.什么是索引 索引是建立在表的一列或多个列上的辅助对象,目的是加快访问表中的数据: Oracle存储索引的数据结构是B*树,位图索引也是如此,只不过是叶子节点不同B*数索引: 索引由根节点.分支节点 ...

  5. Fence9

    题目大意: 求点(0,0),(n,m),(p,0)三点构成的三角形内部(不包括边界)整点的个数. 解题过程:1.直接枚举纵坐标,然后算出两条直线上纵坐标为y的点的横坐标,然后他们中间的点就是符合要求的 ...

  6. Countries in War (POJ 3114) Tarjan缩点+最短路

    题目大意: 在一个有向图中,每两点间通信需要一定的时间,但同一个强连通分量里传递信息不用时间,给两点u,v求他们最小的通信时间.   解题过程: 1.首先把强连通分量缩点,然后遍历每一条边来更新两个强 ...

  7. Redis系列-存储篇hash主要操作函数小结

    阳光透过玻璃,洒在身上,一杯暖茶在手,说不尽的安逸自得,让我有种想再写篇blog的冲动.上篇主要谈了string,这里谈谈hash吧!hash是一些列key value(field value)的映射 ...

  8. WDCP管理面板安装启动EXIF、bcmath完整步骤

    一般我们网站建设的需要,如果使用WDCP面板默认的功能就足够使用,如果需要特殊程序的特定组件支持,就需要独立的安装支持组件.比如一位朋友的程序需要支持EXIF.bcmath组件,这不老蒋寻找解决方法, ...

  9. Javascript——Math对象

    Math 对象是一个固有的对象,无需创建它,直接把 Math 作为对象使用就可以调用其所有属性和方法.这是它与Date,String对象的区别  Math 对象属性 Math 对象方法  

  10. 长理ACM 14-星期几(谌海军)

    题目描述:编一个程序,已知今天是星期几,计算出n天后是星期几.要求使用枚举变量. 输入描述:输入为两个正整数,第一个数n(n<=6)表示今天是星期几,第二个数m(m<=1000),表示求m ...