Alice's present [ZOJ 4801]

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4801

每个位置记录的是左边做靠近他的和他相同大小的id,线段树维护的是最大的id (id最大也即最早出现)

View Code
const int MM = 555555;
#define debug puts("wrong")
#define L(i) i<<1
#define R(i) i<<1|1
int N,M;
int hash[MM];
int num[MM];
int val[MM<<2];
map<int,int>mp;
map<int,int>pos;

void get_data() {
    int i,j,k;
    pos.clear();
    mp.clear();
    for(i=0;i<N;i++) {
        scanf("%d",&num[i]);
        if(mp[num[i]]) hash[i]=pos[num[i]], pos[num[i]]=i;
        else mp[num[i]]=1,hash[i]=-1, pos[num[i]]=i;
    }
//    for(i=0;i<N;i++) printf("%d ",hash[i]); printf("\n");
}
void push_up(int rt) {
    val[rt]=f_max(val[L(rt)],val[R(rt)]);
}
void build(int l,int r,int rt) {
    if(l==r) {
        val[rt]=hash[l];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,L(rt));
    build(mid+1,r,R(rt));
    push_up(rt);
}
int query(int L,int R,int l,int r,int rt) {
    if(L<=l && r<=R) {
        return val[rt];
    }
    int mid=(l+r)>>1,res=-1;
    if(L<=mid)  res=f_max(res,query(L,R,l,mid,L(rt)));
    if(R>mid)  res=f_max(res,query(L,R,mid+1,r,R(rt)));
    return res;
}
void solve() {
    int i,j,k,x,y,tmp;
    build(0,N-1,1);
    scanf("%d",&M);
    while(M--) {
        scanf("%d%d",&x,&y);
        x--, y--;
        tmp=query(x,y,0,N-1,1);
        if(tmp<x) puts("OK");
        else printf("%d\n",num[tmp]);
    }
    printf("\n");
}
int main() {
    while(scanf("%d",&N)!=EOF) get_data(),solve();
}
/*
10
1 2 3 4 1 2 3 4 5 6
*/
原文地址:https://www.cnblogs.com/zhang1107/p/3032262.html