离线,把所有询问按照r从小到大排序,然后用线段树维护对于每一个l对应的最小值。。。。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 500005 #define maxm 500005 #define eps 1e-9 #define mod 1000000007 #define INF 0x3f3f3f3f #define PI (acos(-1.0)) #define lowbit(x) (x&(-x)) #define mp make_pair #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R #define pii pair<int, int> #pragma comment(linker, "/STACK:16777216") typedef long long LL; typedef unsigned long long ULL; using namespace std; LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;} LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;} //head struct node { int l, r, id; }q[maxn]; int minv[maxn << 2]; int lazy[maxn << 2]; int pre[maxn]; int ans[maxn]; int a[maxn]; int b[maxn]; int n, m; int cmp(node a, node b) { return a.r < b.r; } void read() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) scanf("%d", &a[i]), b[i] = a[i]; for(int i = 1; i <= m; i++) scanf("%d%d", &q[i].l, &q[i].r), q[i].id = i; sort(b+1, b+n+1); sort(q+1, q+m+1, cmp); int cnt = unique(b+1, b+n+1) - b - 1; for(int i = 1; i <= n; i++) a[i] = lower_bound(b+1, b+cnt+1, a[i]) - b; } void build(int o, int L, int R) { minv[o] = n, lazy[o] = INF; if(L == R) return; int mid = (L + R) >> 1; build(lson); build(rson); } void pushup(int o) { minv[o] = min(minv[ls], minv[rs]); } void pushdown(int o) { if(lazy[o] != INF) { minv[ls] = min(minv[ls], lazy[o]); minv[rs] = min(minv[rs], lazy[o]); lazy[ls] = min(lazy[ls], lazy[o]); lazy[rs] = min(lazy[rs], lazy[o]); lazy[o] = INF; } } void update(int o, int L, int R, int ql, int qr, int v) { if(ql <= L && qr >= R) { minv[o] = min(minv[o], v); lazy[o] = min(lazy[o], v); return; } pushdown(o); int mid = (L + R) >> 1; if(ql <= mid) update(lson, ql, qr, v); if(qr > mid) update(rson, ql, qr, v); pushup(o); } int query(int o, int L, int R, int ql, int qr) { if(ql <= L && qr >= R) return minv[o]; int ans = INF, mid = (L + R) >> 1; pushdown(o); if(ql <= mid) ans = min(ans, query(lson, ql, qr)); if(qr > mid) ans = min(ans, query(rson, ql, qr)); pushup(o); return ans; } void work() { build(1, 1, n); for(int i = 1; i <= n; i++) pre[i] = n; for(int i = 1, j = 1; i <= n && j <= m; i++) { if(pre[a[i]] == n) pre[a[i]] = i; else update(1, 1, n, 1, pre[a[i]], i - pre[a[i]]), pre[a[i]] = i; while(j <= m && q[j].r == i) { ans[q[j].id] = query(1, 1, n, q[j].l, n); j++; } } for(int i = 1; i <= m; i++) printf("%d\n", ans[i] == n ? -1 : ans[i]); } int main() { read(); work(); return 0; }