FZU 2226 信心题

来源:互联网 发布:软考初级程序员视频 编辑:程序博客网 时间:2024/04/30 06:24

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;}

1 1
原创粉丝点击