UVALive 5881 Unique Encryption Keys

用线段树求最小值就行了

#include<iostream>
#include<cstring>
#include <cstdio>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include <set>
#include<ctime>
#include<cmath>
#include <cstdlib>
#include <algorithm>
#include <iomanip>
#include <bitset>
#include <stack>
using namespace std;

#define LL long long
#define INF ((1<<31)-1)
#define Max 1000005
#define L(x) ((x)<<1)
#define R(x) ((x)<<1|1)

struct N{
    int right,val;
}a[Max];

struct node{
    int l,r;
    int mid(){ return (l+r)>>1; }
    int min_,val;
}sg[3*Max];
int ar[Max];
int ans_min,ans_val;

void build(int l, int r, int id){
    sg[id].l = l; sg[id].r = r;
    if(l == r) {
        sg[id].min_ = a[l].right;
        sg[id].val= a[l].val;
    }
    else{
        build(l, sg[id].mid(), L(id));
        build(sg[id].mid()+1, r, R(id));
        if(sg[L(id)].min_<sg[R(id)].min_){
            sg[id].min_=sg[L(id)].min_;
            sg[id].val=sg[L(id)].val;
        }
        if(sg[L(id)].min_>=sg[R(id)].min_){
            sg[id].min_=sg[R(id)].min_;
            sg[id].val=sg[R(id)].val;
        }
    }
}
void query(int l,int r,int id){
    if(sg[id].l==l&&sg[id].r==r) {
        if(ans_min>=sg[id].min_){
            ans_min=sg[id].min_;
            ans_val=sg[id].val;
        }
    }
    else {
        if(l<=sg[L(id)].r)
            query(l,min(r,sg[L(id)].r),L(id));
        if(r>=sg[R(id)].l)
            query(max(l,sg[R(id)].l),r,R(id));
    }
}

int main(){
    int n,Q;
    while(scanf("%d%d",&n,&Q)!=EOF){
        if(!n&&!Q) return 0;
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++){
            scanf("%d",&ar[i]);
        }
        map<int,int> mpp;
        for(int i=1;i<=n;i++){
            if(!mpp[ar[i]]){
                mpp[ar[i]]=i;
            }else {
                a[ mpp[ar[i]] ].right=i;
                a[ mpp[ar[i]] ].val=ar[i];
                mpp[ar[i]]=i;
            }
        }
        for(int i=1;i<=n;i++){
            if(!a[i].right)
                a[i].right=INF;
        }
        build(1,n,1);
        while(Q--){
            int l,r;
            scanf("%d%d",&l,&r);
            ans_min=INF;
            query(l,r,1);
            if(ans_min==INF){
                printf("OK\n");
            }else {
                if(ans_min<=r)printf("%d\n",ans_val);
                else printf("OK\n"); 
            }
        }
        printf("\n");
    }
}
posted @ 2012-04-18 22:19  HaoHua_Lee  阅读(324)  评论(0编辑  收藏  举报