您的位置:首页 > 大数据 > 人工智能

2013 Multi-University Training Contest 3

2013-07-31 19:56 369 查看
HDU-4622 Reincarnation

题意:给定一个字符串,有Q次询问,每次询问得出区间[L, R]内有多少个不同的子串。

分析:后缀数组搞,不过hash+dp也能够搞定这题,详解见/content/3869448.html

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;

typedef long long LL;

inline int sign(double);
struct Point {
double x, y;
Point () {}
Point (double _x, double _y) : x(_x), y(_y) {}
void read() {
scanf("%lf %lf", &x, &y);
}
bool operator < (const Point &t) const {
if (sign(x-t.x) != 0) return sign(x-t.x) < 0;
return sign(y-t.y) < 0;
}
};

const int N = 100005;
const double eps = 1e-6;
int n, m, Div
;
Point pt
;
double ret;

inline int sign(double x) {
return x < -eps ? -1 : x > eps;
}

double dist(const Point &a, const Point &b) {
return sqrt(1.0*(a.x-b.x)*(a.x-b.x) + 1.0*(a.y-b.y)*(a.y-b.y));
}

bool cmpX(const Point &a, const Point &b) {
return a.x < b.x;
}

bool cmpY(const Point &a, const Point &b) {
return a.y < b.y;
}

void BuildKD(int l, int r, Point p[]) {
if (l >= r) return; // 如果已经划分到叶子节点
int mid = l + r >> 1;
double MinX, MaxX, MinY, MaxY;
MinX = min_element(p+l, p+r+1, cmpX)->x;
MaxX = max_element(p+l, p+r+1, cmpX)->x;
MinY = min_element(p+l, p+r+1, cmpY)->y;
MaxY = max_element(p+l, p+r+1, cmpY)->y;
Div[mid] = (MaxX - MinX) > (MaxY - MinY);
// Div[i]为0表示按照x轴划分,为1表示按照y轴划分,划分的依据仅仅是那个方向的取值跨度大
nth_element(p+l, p+mid, p+r+1, Div[mid] ? cmpX : cmpY);
BuildKD(l, mid-1, p);
BuildKD(mid+1, r, p);
}

void Find(int l, int r, const Point &a, Point p[]) {
if (l > r) return;
int mid = l + r >> 1;
double dis = dist(a, p[mid]);
ret = min(ret, dis);
double d = Div[mid] ? (a.x - p[mid].x) : (a.y - p[mid].y);
int l1 = l, l2 = mid+1;
int r1 = mid-1, r2 = r;
if (sign(d) > 0) swap(l1, l2), swap(r1, r2);
Find(l1, r1, a, p);
if (sign(ret - fabs(d)) > 0) Find(l2, r2, a, p);
}

int main() {
// n个节点,m次询问,返回离询问点最近的节点距离
while (scanf("%d %d", &n, &m) != EOF) {
for (int i = 0; i < n; ++i) {
pt[i].read();
}
BuildKD(0, n-1, pt);
while (m--) {
Point p;
p.read();
ret = 1e30;
Find(0, n-1, p, pt);
printf("%f\n", ret);
}
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: