UVA 11898 - Killer Problem
题意:给定一个序列,每次询问一个[l,r],求出这个区间中选取两个不同位置的数字,他们的绝对值最小
思路:想线段数,树状数组,RMQ之类搞,根本想不通怎么搞,于是看了下别人的讨论,发现居然是大力出奇迹,不过还是有用到点原理,就是由于数字最多1W,如果询问区间超过1W的话,必然会有两个一样的数字,绝对值就是0了,这样一剪,再利用计数排序去找靠近的两两个数字,就能过了,复杂度为O(10^8)
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200005;
const int M = 10005;
int t, n, num[N], cnt[M];
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &num[i]);
int q, l, r;
scanf("%d", &q);
while (q--) {
scanf("%d%d", &l, &r);
if (r - l + 1 >= 10000) {
printf("0\n");
continue;
}
memset(cnt, 0, sizeof(cnt));
int flag = 1, Max = 0;
for (int i = l; i <= r; i++) {
cnt[num[i]]++;
Max = max(Max, num[i]);
if (cnt[num[i]] == 2) {
printf("0\n");
flag = 0;
break;
}
}
if (flag) {
int pre = -1;
int ans = 10000;
for (int i = 1; i <= Max; i++) {
if (cnt[i]) {
if (pre != -1)
ans = min(ans, i - pre);
pre = i;
}
}
printf("%d\n", ans);
}
}
}
return 0;
}