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 */