将与每个点相同值的前面一个位置记录下来,然后线段树维护即可...
果然,我很弱,一直没想到怎么维护...还看错题,以为找重复里面值最大的...
其实就是维护这些位置就好...
#include "cstdio"
#include "cstring"
#include "iostream"
#include "algorithm"
using namespace std;
typedef pair<int, int> PII;
const int N = 500001;
PII dat[N];
int pos[N], val[N], seg[N<<2];
void build(int L, int R, int rt){
if(L==R){
seg[rt]=pos[L];
return;
}
int mid = (L+R)>>1;
build(L, mid, rt<<1);
build(mid+1, R, rt<<1|1);
seg[rt]=max(seg[rt<<1], seg[rt<<1|1]);
}
int ques(int l, int r, int L, int R, int rt){
if(l<=L && R<=r) {
return seg[rt];
}
int mid = (L+R)>>1;
int lv =-1, rv = -1;
if (l<=mid){
lv = ques(l, r, L, mid, rt<<1);
}
if(r>mid){
rv = ques(l, r, mid+1, R, rt<<1|1);
}
return max(lv, rv);
}
int main()
{
int n, m, x, l, r, i;
while(~scanf("%d", &n)){
for (i=1; i<=n; ++i)
{
scanf("%d", &val[i]);
dat[i].first = val[i];
dat[i].second = i;
}
sort(dat+1, dat+n+1);
pos[1] = -1;
for (i=2; i<=n; ++i)
{
if (dat[i-1].first==dat[i].first) {
pos[dat[i].second] = dat[i-1].second;
}
else {
pos[dat[i].second] = -1;
}
}
build(1, n, 1);
scanf("%d", &m);
while(m--){
scanf("%d%d", &l, &r);
x = ques(l, r, 1, n, 1);
if (x==-1 || x<l)
{
printf("OK\n");
}
else {
printf("%d\n", val[x]);
}
}
puts("");
}
return 0;
}