Problem Description
给定一个含有n个数字的数列,每个数字都有一个值a[i](下标从1开始)。定义第i个数字和第j个数字间的距离dis(i,j)=abs(i-j)。
接下来给出q个询问,每次询问一个区间[l,r],要求求出一对数字(i,j)(l<=i<=j<=r),使得a[i]=a[j]并且dis(i,j)最大,由于这样的数对可能有多个,因此答案只要输出dis。
Input
题目包含多组数据
每组数据第一行一个数n
第二行n个数字,表示数列a
第三行一个数字q,表示询问个数
接下来q行,每行两个数l,r,表示询问
N<=10^5
Q<=10^4
1<=a[i]<=10^3
1<=l<=r<=n
Output
每个询问输出一个数组dis
Sample Input
5
1 2 3 1 2
3
3 3
2 5
1 5
Sample Output
0
3
3
离线,然后排序乱搞
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<bitset>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<functional>
using namespace std;
typedef long long LL;
const int low(int x) { return x&-x; }
const int INF = 0x7FFFFFFF;
const int mod = 1e9 + 7;
const int maxn = 1e4 + 10;
int n, m, x, ans[maxn];
int L[maxn], R[maxn];
vector<int> p[maxn];
struct point
{
int l, r, id;
void read(int x) { id = x; scanf("%d%d", &l, &r); }
}q[maxn], q1[maxn], q2[maxn];
bool cmp1(const point &a, const point &b)
{
return a.l < b.l;
}
bool cmp2(const point &a, const point &b)
{
return a.r < b.r;
}
int main()
{
while (scanf("%d", &n) != EOF)
{
for (int i = 1; i <= 1000; i++) p[i].clear();
for (int i = 1; i <= n; i++)
{
scanf("%d", &x);
p[x].push_back(i);
}
scanf("%d", &m);
for (int i = 0; i < m; i++)
{
q[i].read(i);
q1[i] = q2[i] = q[i];
ans[i] = 0;
}
sort(q1, q1 + m, cmp1);
sort(q2, q2 + m, cmp2);
for (int i = 1; i <= 1000; i++)
{
if (!p[i].size()) continue;
int k1 = 0, k2 = 0;
for (int j = 0; j < p[i].size(); j++)
{
while (k1 < m && q1[k1].l <= p[i][j])
{
L[q1[k1++].id] = p[i][j];
}
while (k2 < m && q2[k2].r < p[i][j])
{
R[q2[k2++].id] = j ? p[i][j - 1] : 0;
}
}
while (k1 < m) L[q1[k1++].id] = n + 1;
while (k2 < m) R[q2[k2++].id] = p[i].size() ? p[i][p[i].size() - 1] : 0;
for (int j = 0; j < m; j++)
{
if (L[j] >= q[j].l&&L[j] <= q[j].r)
{
if (R[j] >= q[j].l&&R[j] <= q[j].r)
{
ans[j] = max(ans[j], R[j] - L[j]);
}
}
}
}
for (int i = 0; i < m; i++) printf("%d\n", ans[i]);
}
return 0;
}