2012-0007

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

先对输入数字进行hash处理
尾指针一开始处于位置1
头指针正向扫描数列,如果头指针指向的当前数字在之前出现过(in[ a[head] ]=true),
则令尾指针不停加一,并且使 in[ a[tail] ]变为false,直到in[ a[head] ]=false为止,
可以发现此时tail指针所在位置,就是当前数字之前一次在数列中出现过的位置,令pos[head]=tail即可
pos[i]表示对于以第i个位置结尾的区间来说,所求答案所在的位置。     时间复杂度:O(n)                                  ————————By kotori
{{{
#include<stdio.h>
#include<cstring>
#include<map>
#define maxn 524288
using namespace std;
int a[maxn],pos[maxn];
int link[maxn];
bool in[maxn];
int n,m,beg,end;
map<int,int>hash;
int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  int i,j,tmp;
  while(scanf("%d",&n)!=EOF){
    memset(pos,0,sizeof(pos));
    memset(in,0,sizeof(in));
    memset(link,0,sizeof(link));
    hash.clear();
    tmp=0;
    for(i=1;i<=n;i++){
      scanf("%d",&j);
      if(hash[j]==0){
        hash[j]=++tmp;
        link[tmp]=j;
      }
      a[i]=hash[j];
    }
    for(i=1,j=0;i<=n;i++){
      if(in[a[i]])
        while(in[a[i]])
          in[a[++j]]=0;
      pos[i]=j;
      in[a[i]]=1;
    }
    scanf("%d",&m);
    for(i=1;i<=m;i++){
      scanf("%d%d",&beg,&end);
      if(pos[end]<beg)
        printf("OK\n");
      else
        printf("%d\n",link[ a[pos[end]] ]);
    }
    printf("\n");
  }
  return 0;
}
}}}

先对输入数字进行hash处理

尾指针一开始处于位置1

头指针正向扫描数列,如果头指针指向的当前数字在之前出现过(in[ a[head] ]=true),

则令尾指针不停加一,并且使 in[ a[tail] ]变为false,直到in[ a[head] ]=false为止,

可以发现此时tail指针所在位置,就是当前数字之前一次在数列中出现过的位置,令pos[head]=tail即可

pos[i]表示对于以第i个位置结尾的区间来说,所求答案所在的位置。 时间复杂度:O(n) ————————By kotori

#include<stdio.h>
#include<cstring>
#include<map>
#define maxn 524288
using namespace std;
int a[maxn],pos[maxn];
int link[maxn];
bool in[maxn];
int n,m,beg,end;
map<int,int>hash;
int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  int i,j,tmp;
  while(scanf("%d",&n)!=EOF){
    memset(pos,0,sizeof(pos));
    memset(in,0,sizeof(in));
    memset(link,0,sizeof(link));
    hash.clear();
    tmp=0;
    for(i=1;i<=n;i++){
      scanf("%d",&j);
      if(hash[j]==0){
        hash[j]=++tmp;
        link[tmp]=j;
      }
      a[i]=hash[j];
    }
    for(i=1,j=0;i<=n;i++){
      if(in[a[i]])
        while(in[a[i]])
          in[a[++j]]=0;
      pos[i]=j;
      in[a[i]]=1;
    }
    scanf("%d",&m);
    for(i=1;i<=m;i++){
      scanf("%d%d",&beg,&end);
      if(pos[end]<beg)
        printf("OK\n");
      else
        printf("%d\n",link[ a[pos[end]] ]);
    }
    printf("\n");
  }
  return 0;
}