UVALive 5881 Unique Encryption Keys

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3892


题意:给出有n个数的序列,进行m次询问,每次询问给出一个区间[l,r],问区间中是否有重复的数


思路:把整个序列进行一次预处理,求出与第i个数相等且排在它前面的数保存在pr[i],最后询问时枚举区间每一个数,比较pr[i]与l的大小,题目给的时间比较宽松,所以水过去了,更好的做法是利用线段树,或者pr[i]标记离第i个数最近且有重复出现的数字的位置


下面是我自己的代码(因为我要用数组记录的原因进行了离散化)


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

struct Node
{
    int val,pos;
}temp[1000030],s[1000030];

bool cmp(Node p,Node q)
{
    return p.val<q.val;
}

int vis[1000030],pr[1000030];

int main()
{
    int n,m;
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        if (n==0 && m==0) break;
        memset(vis,-1,sizeof(vis));
        memset(pr,-1,sizeof(pr));
        for (int i=0;i<n;i++)
        {

            scanf("%d",&temp[i].val);
            temp[i].pos=i;
        }
        sort(temp,temp+n,cmp);

             s[temp[0].pos].val=0;
             s[temp[0].pos].pos=temp[0].val;
        int tem=0;
        for (int i=1;i<n;i++)
        {
            if (temp[i].val!=temp[i-1].val)
            {
                tem++;
                s[temp[i].pos].val=tem;
                s[temp[i].pos].pos=temp[i].val;

            }
            else
            {
                s[temp[i].pos].val=tem;
                s[temp[i].pos].pos=temp[i].val;

            }

        }
//        for (int i=0;i<n;i++)
//        {
//            cout<<":"<<s[i].val<<endl;
//        }
        for (int i=0;i<n;i++)
        {
            if (vis[s[i].val]!=-1)
            {
                pr[i]=vis[s[i].val];
                vis[s[i].val]=i;
            }
            else
            {
                vis[s[i].val]=i;
            }
        }

        for (int i=0;i<m;i++)
        {
            int l,r,flag=1;
            scanf("%d%d",&l,&r);

            for (int j=l-1;j<r;j++)
            {
                if (pr[j]>=l-1)
                {
                  cout<<s[j].pos<<endl;
                  flag=0;
                  break;
                }
            }
            if (flag==1) cout<<"OK"<<endl;
        }
        cout<<endl;
    }
}


你可能感兴趣的:(ACM)