题目大意:
给你n个数,第i个数为a[i],然后给出m,接着m行,每行有两个数u,v表示询问[u,v]这段区间是否有重复的数,没有输出“OK”,有的话,输出从区间右边向左看起,第一个出现次数等于2的数。
( 3≤ n ≤ 500,000)( 1≤ u< v≤ n )(a[i]<2^31-1)
题解:
1.离线做法:将区间按照右端点从小到达排序,然后开3个指针,l,r,x从右向左扫描,当发现某个数出现两次时,做处理,详见程序。
2.在线做法:用线段树记录每个点的左边离他最近的数出现的位置,这样就转化为了求区间最值问题,碰到一个询问区间[l,r],求区间最值,如果区间最值为x,x>=l,那么结果即是a[l],否则说明没有出现重复的数。
离线做法:
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<algorithm>
using namespace std;
map<int,int>mymap;
int n,m;
int a[1000000];
struct couple
{
int l,r,id;
int data;
}q[1000000];
bool cmpr(couple a,couple b)
{
return a.r<b.r;
}
bool cmpid(couple a,couple b)
{
return a.id<b.id;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
mymap.clear();
memset(q,0,sizeof(q));//注意q必须初始化,否则会出错!因为q.data值可能本次不会更改,这样会用到上次的结果
//这里让我WA了好多次
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+1,q+1+m,cmpr);
int x=m,r=n;
for(int i=n;i>=1;i--)
{
if(mymap.count(a[i])<=0) mymap[a[i]]=i;
else
{
int lim=mymap[a[i]];
while(x>=1 && q[x].r>=lim)
{
if(q[x].l<=i)q[x].data=a[i];else q[x].data=0;
x--;
}
while(r>=1 && r>=lim)
{
mymap.erase(a[r]);
r--;
}
mymap[a[i]]=i;
}
}
sort(q+1,q+1+m,cmpid);
for(int i=1;i<=m;i++)
if(q[i].data==0)printf("OK\n");
else printf("%d\n",q[i].data);
printf("\n");
}
return 0;
}
在线做法:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
inline int lson(int x){return 2*x;}
inline int rson(int x){return 2*x+1;}
const int maxn=600001;
int a[maxn];
struct Node
{
int l,r,maxx;
}node[maxn*4];
map<int,int>mymap;
int n,m;
void build(int l,int r,int th)
{
node[th].l=l;
node[th].r=r;
node[th].maxx=0;
if(l==r)return;
int mid=(l+r)>>1;
build(l,mid,lson(th));
build(mid+1,r,rson(th));
}
void updata(int l,int r,int th,int c)
{
if(node[th].l==l && node[th].r==r)
{
node[th].maxx=c;
return;
}
int mid=(node[th].l+node[th].r)>>1;
if(r<=mid)
updata(l,r,lson(th),c);
else if(l>mid)
updata(l,r,rson(th),c);
else
{
updata(l,mid,lson(th),c);
updata(mid+1,r,rson(th),c);
}
node[th].maxx=max(node[lson(th)].maxx,node[rson(th)].maxx);
}
int query(int l,int r,int th)
{
if(node[th].l==l && node[th].r==r)
return node[th].maxx;
int mid=(node[th].l+node[th].r)>>1;
if(r<=mid)
return query(l,r,lson(th));
if(l>mid)
return query(l,r,rson(th));
else
return max(query(l,mid,lson(th)),query(mid+1,r,rson(th)));
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
mymap.clear();
build(1,n,1);
for(int i=1;i<=n;i++)
if(mymap.count(a[i])==0)
{
mymap[a[i]]=i;
}
else
{
updata(i,i,1,mymap[a[i]]);
mymap[a[i]]=i;
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int l,r;
scanf("%d%d",&l,&r);
int ans=query(l,r,1);
if(ans>=l)printf("%d\n",a[ans]);
else printf("OK\n");
}
printf("\n");
}
return 0;
}