首页 > 代码库 > [COJ0988]WZJ的数据结构(负十二)

[COJ0988]WZJ的数据结构(负十二)

[COJ0988]WZJ的数据结构(负十二)

试题描述

技术分享

输入

见题目,注意本题不能用文件输入输出

输出

见题目,注意本题不能用文件输入输出

输入示例

4100000010000000041 11 21 31 4

输出示例

0121

数据规模及约定

1≤N≤1500,M≤N×N 且 M≤300000。 

题解

我们先预处理出 d[i][j] 表示距离 (i, j) 这个点最近的点(只考虑第 i 行)的欧几里得距离。那么我们可以枚举行数 i,然后变成一维问题从左往右扫,设 f(i, j) 为离该点最近的点的欧几里得距离(即答案),那么有 f(i, j) = min{ d[i][k] + (j - k)2 | 1 ≤ k ≤ j },显然可以用斜率优化来搞。

#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <stack>#include <vector>#include <queue>#include <cstring>#include <string>#include <map>#include <set>using namespace std;const int BufferSize = 1 << 16;char buffer[BufferSize], *Head, *Tail;inline char Getchar() {    if(Head == Tail) {        int l = fread(buffer, 1, BufferSize, stdin);        Tail = (Head = buffer) + l;    }    return *Head++;}int read() {    int x = 0, f = 1; char c = getchar();    while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = getchar(); }    while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = getchar(); }    return x * f;}#define maxn 1510#define oo 2147483647int n, d[maxn][maxn], f[maxn][maxn];char Map[maxn][maxn];int sqr(int x) { return x * x; }struct Node {	int x, y;	Node() {}	Node(int _, int __): x(_), y(__) {}} q[maxn];double slop(Node a, Node b) {	return ((double)a.y - b.y) / ((double)a.x - b.x);}int main() {	n = read();	for(int i = 1; i <= n; i++) scanf("%s", Map[i] + 1);		for(int i = 1; i <= n; i++)		for(int j = 1; j <= n; j++) d[i][j] = oo;	for(int j = 1; j <= n; j++) {		int tmp = -1;		for(int i = 1; i <= n; i++) {			if(Map[i][j] == ‘1‘) tmp = i;			if(tmp > 0) d[i][j] = min(d[i][j], sqr(i - tmp));		}		tmp = -1;		for(int i = n; i; i--) {			if(Map[i][j] == ‘1‘) tmp = i;			if(tmp > 0) d[i][j] = min(d[i][j], sqr(i - tmp));		}	}	for(int i = 1; i <= n; i++) {		int ql = 1, qr = 0;		for(int j = 1; j <= n; j++) {			if(d[i][j] < oo) {				Node t(j, d[i][j] + sqr(j));				while(ql < qr && slop(q[qr-1], q[qr]) > slop(q[qr], t)) qr--;				q[++qr] = t;			}			while(ql < qr && slop(q[ql], q[ql+1]) < 2.0 * j) ql++;			if(ql <= qr) f[i][j] = q[ql].y - 2 * j * q[ql].x + sqr(j);//			printf("%d %d: %d\n", i, j, f[i][j]);		}		ql = 1; qr = 0;		for(int j = n; j; j--) {			if(d[i][j] < oo) {				Node t(j, d[i][j] + sqr(j));				while(ql < qr && slop(q[qr-1], q[qr]) < slop(q[qr], t)) qr--;				q[++qr] = t;			}			while(ql < qr && slop(q[ql], q[ql+1]) > 2.0 * j) ql++;			if(ql <= qr) f[i][j] = min(f[i][j] ? f[i][j] : oo, q[ql].y - 2 * j * q[ql].x + sqr(j));		}	}		int q = read();	while(q--) {		int a = read(), b = read();		printf("%d\n", f[a][b]);	}		return 0;}

 

[COJ0988]WZJ的数据结构(负十二)