1.互质集合:
a.定义:Disjoint Sets是一种用互质集合对数据进行分类管理的数据结构
b.代码:
2.范围搜索:
a.题目:判断给定的点是否在给定的矩形内
b.分析:
1)将二维空间的点降维至一维坐标系
2)将这些点分别放入同一颗二叉树的不同的纵坐标和横坐标当中
c.代码:
a.定义:Disjoint Sets是一种用互质集合对数据进行分类管理的数据结构
b.代码:
//
// Created by 叶子 on 2018/2/6.
// 互质的集合
//
#include "iostream"
#include "vector"
using namespace std;
class DisjointSet{
public :
vector<int> rank,p;
DisjointSet(){}
DisjointSet(int size) {
rank.resize(size, 0);
p.resize(size, 0);
for (int i = 0; i < size; i++) makeSet(i);
}
void makeSet(int x) {
p[x] = x;
rank[x] = 0;
}
bool same(int x, int y) {
return findSet(x) == findSet(y);
}
void unite(int x,int y){
link(findSet(x) ,findSet(y));
}
void link(int x,int y){
if ( rank[x] > rank[y] ){
p[y] = x;
}else{
p[x] = y;
if ( rank[x] == rank[y]){
rank[y] ++;
}
}
}
int findSet(int x){
if ( x!= p[x]){
p[x] = findSet(p[x]);
}
return p[x];
}
};
int main(){
int n,a,b,q,t;
cin >> n >> q;
DisjointSet ds = DisjointSet(n);
for ( int i = 0 ; i < q ; i ++){
cin >> t >> a >> b;
if ( t == 0) ds.unite(a,b);
else if ( t == 1 ){
if ( ds.same(a,b) ) cout << 1 << endl;
else cout << 0 << endl;
}
}
}
2.范围搜索:
a.题目:判断给定的点是否在给定的矩形内
b.分析:
1)将二维空间的点降维至一维坐标系
2)将这些点分别放入同一颗二叉树的不同的纵坐标和横坐标当中
c.代码:
//
// Created by 叶子 on 2018/2/6.
// 给定一些指定点,判断这些点是否在给定的矩形内
//
#include "cstdio"
#include "algorithm"
#include "vector"
using namespace std;
class Node{
public :
int location;
int p,l,r;
Node(){}
};
class Point{
public:
int id,x,y;
Point(){}
Point(int id,int x,int y):id(id),x(x),y(y){}
bool operator < ( const Point &p) const {
return id <p.id;
}
void print(){
printf("%d\n",id);
}
};
static const int MAX = 1000000;
static const int NIL = -1;
int N;
Point P[MAX];
Node T[MAX];
int np;
bool lessX(const Point &p1,const Point &p2){ return p1.x < p2.x;}
bool lessY(const Point &p1,const Point &p2){ return p1.y < p2.y;}
int makeKDTree(int l,int r ,int depth){
if ( !(l<r )) return NIL;
int mid = ( l + r) /2;
int t = np ++;
if ( depth % 2 == 0 ){
sort(P+1,P+r,lessX);
}else{
sort(P+1,P+r,lessY);
}
T[t].location = mid;
T[t].l = makeKDTree(1,mid,depth+1);
T[t].r = makeKDTree(mid+1,r,depth+1);
return t;
}
void find(int v,int sx,int tx,int sy,int ty,int depth,vector<Point> & ans){
int x = P[T[v].location].x;
int y = P[T[v].location].y;
if ( sx <= x && sy <= y && y <= ty ){
ans.push_back(P[T[v].location]);
}
if ( depth % 2 == 0){
if ( T[v].l != NIL){
if ( sx <= x ) find(T[v].l ,sx,tx,sy,ty,depth+1,ans);
}
if ( T[v].r != NIL){
if ( x <= tx ) find(T[v].r ,sx,tx,sy,ty,depth+1,ans);
}
}else{
if ( T[v].l != NIL){
if ( sy <= y ) find(T[v].l ,sx,tx,sy,ty,depth+1,ans);
}
if ( T[v].r != NIL){
if ( y <= ty ) find(T[v].r ,sx,tx,sy,ty,depth+1,ans);
}
}
}
int main(){
int x,y;
scanf("%d",&N);
for ( int i = 0 ; i < N ; i ++){
scanf("%d %d",&x,&y);
P[i] = Point(i,x,y);
T[i].l = T[i].r = T[i].p = NIL;
}
np = 0 ;
int root = makeKDTree(0,N,0);
int q;
scanf("%d",&q);
int sx,tx,sy,ty;
vector<Point> ans;
for ( int i = 0 ; i < q ; i ++){
scanf("%d %d %d %d",&sx,&tx,&sy,&ty);
ans.clear();
find(root,sx,tx,sy,ty,0,ans);
sort(ans.begin(),ans.end());
for ( int j = 0 ; j < ans.size() ; j ++){
ans[j].print();
}
printf("\n");
}
return 0;
}