HDU 5862 Counting Intersections(樹狀陣列+掃描線+離散化)
Counting Intersections
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1296 Accepted Submission(s): 407
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.
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.
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
Author
BUPT
Source
題意:
給你幾根與座標軸平行的線,問你產生幾個交點。
POINT:
樹狀陣列的區間值是儲存了y區間內有幾根橫線。
把y軸離散化。橫線只要看成2個點,和豎線一起依x軸從小到大排序。
然後從左向右掃描,掃描到左端點,就y點+1,右端點就-1,掃描到豎線,就查詢豎線上的y區間內右幾根橫線。(單點修改,區間查詢)
注意端點與線重合的情況,優先掃描左端點,然後再掃描豎線,最後是右端點,不然答案會少。畫一個右端點和豎線重合的圖思考一下。
(就是為了去補這題多校,才去做了很多線段樹和樹狀陣列,終於把這題1A了,思考時間也不長,寫的很快還沒有錯,那麼線段樹和樹狀陣列也就告一段落,下面學習RMQ吧。自己還有很多要學的呢。
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int N = 100050*5;
#define LL long long
struct node//離散縱座標
{
int x,y1,y2;
int flag;//零代表豎線, 1代表橫線左端點 -1右端點
}dian[N];
int haha[N];
int mm;
int yy[N];
int num[N];
int lowbit(int x)
{
return x&-x;
}
void add(int x,int c)
{
while(x<=mm)
{
num[x]+=c;
x+=lowbit(x);
}
}
LL query(int x)
{
LL ans=0;
while(x>=1)
{
ans+=(LL)num[x];
x-=lowbit(x);
}
return ans;
}
int Discretization(int y)
{
return (int)(lower_bound(yy+1,yy+1+mm,y)-yy);
}
bool cmd(node a,node b)
{
if(a.x!=b.x)
return a.x<b.x;
else
return a.flag>b.flag;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
memset(dian,0,sizeof dian);
memset(haha,0,sizeof haha);
memset(yy,0,sizeof yy);
memset(num,0,sizeof num);
int m=0;
int my=0;
for(int i=1;i<=n;i++)
{
int x1,x2,y1,y2;
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
if(x1>x2) swap(x1,x2);
if(y1>y2) swap(y1,y2);
if(x1==x2)
{
dian[++m].x=x1;
dian[m].flag=0,dian[m].y1=y1,dian[m].y2=y2;
yy[++my]=y1;
yy[++my]=y2;
}
else
{
dian[++m].x=x1;
dian[m].flag=1,dian[m].y1=dian[m].y2=y1;
dian[++m].x=x2;
dian[m].flag=-1,dian[m].y1=dian[m].y2=y2;
yy[++my]=y1;
}
}
sort(yy+1,yy+1+my);
mm=1;
for(int i=2;i<=my;i++)
{
if(yy[i-1]!=yy[i]) yy[++mm]=yy[i];
}
sort(dian+1,dian+1+m,cmd);
LL ans=0;
for(int i=1;i<=m;i++)
{
if(dian[i].flag==0)//豎線
{
int Y=Discretization(dian[i].y2);
int y=Discretization(dian[i].y1);
ans+=query(Y)-query(y-1);
}
else if(dian[i].flag==-1)//右端點
{
int y=Discretization(dian[i].y1);
add(y,-1);
}
else
{
int y=Discretization(dian[i].y1);
add(y,1);
}
}
printf("%lld\n",ans);
}
}
相關文章
- HDU 1542 Atlantis (線段樹+離散化+掃描線)
- HDU 1255 覆蓋的面積(線段樹+掃描線+離散化)
- HDH 1264 Counting Squares (線段樹+掃描線|暴力)
- HDU 1556 Color the ball(線段樹|樹狀陣列)陣列
- LeetCode 493. 翻轉對(歸併排序 || 離散化+樹狀陣列)LeetCode排序陣列
- HDU 1541 & POJ 2352 Stars (樹狀陣列)陣列
- HDU 1542 Atlantis(掃描線)
- Leetcode 327. 區間和的個數 (字首和 + 離散化 + 樹狀陣列)LeetCode陣列
- HDU 2689 Sort it【樹狀陣列求逆序對】陣列
- HDU 6274 Master of Sequence(思維+樹狀陣列+二分)AST陣列
- HDU 1556【區間更新+單點查詢 樹狀陣列】陣列
- 樹狀陣列陣列
- 解析樹狀陣列陣列
- ECNU OJ 3353 塗黑板(線段樹離散化)
- HDU1166 敵兵佈陣【樹狀陣列 單點修改+區間查詢】陣列
- HDU 3333 Turing Tree(線段樹+離線操作)
- 二維樹狀陣列陣列
- 樹狀陣列詳解陣列
- 樹狀陣列基礎陣列
- 樹狀陣列模板題 & (樹狀陣列 1:單點修改,區間查詢)陣列
- 樹狀陣列快速入門陣列
- 樹狀陣列和逆序對陣列
- 【筆記/模板】樹狀陣列筆記陣列
- leetcode 陣列專題 06-掃描線演算法(Sweep Line Algorithm)LeetCode陣列演算法Go
- POJ 2528 Mayor's posters (線段樹 區間更新+離散化)
- MySQL中的全表掃描和索引樹掃描MySql索引
- POJ-2352 Stars(樹狀陣列)陣列
- 樹狀陣列模板+習題集陣列
- 樹狀陣列(我是真小白)陣列
- 資料結構——樹狀陣列資料結構陣列
- 樹狀陣列3種基本操作陣列
- LeetCode C++ 劍指 Offer 51. 陣列中的逆序對【歸併排序/樹狀陣列/線段樹】LeetCodeC++陣列排序
- HDU 1166 敵兵佈陣 (線段樹 插點問線)
- 離散化
- bzoj3155: Preprefix sum(樹狀陣列)陣列
- 【luogu3368】模板 樹狀陣列 2陣列
- 洛谷題單指南-二叉堆與樹狀陣列-P3368 【模板】樹狀陣列 2陣列
- POJ 3468 【區間修改+區間查詢 樹狀陣列 | 線段樹 | 分塊】陣列