2012-A3-0007
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
题意:给出一串长度为N的序列,给出M组询问,每组询问一段[l,r]区间内的重复情况,如有输出最后一组重复的数字,否者输出OK.
首先把序列里的元素离散化,对于序列里每个元素找到在它之前的最后一个与之重复的,记录下标。
根据题意,重复位置的取最靠后的,所以上述的下标都只要存个前缀最大值d[i],
对于区间[l,r],如果 d[y]>=x,就有重复,否者没有。
离散化要O(n log n),查询单次O(1)
{{{
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef unsigned num;
num a[1<<19],b[1<<19],c[1<<19],d[1<<19];
int main(){
for(num n,m,q;scanf("%u",&n)==1;putchar('\n')){
for(num i=0;i<n;++i)scanf("%u",a+i);
memcpy(b,a,n<<2);
sort(b,b+n);m=unique(b,b+n)-b;
memset(c,0,n<<2);
for(num i=0,j;i<n;c[j]=++i)
d[i+1]=max(d[i],c[j=upper_bound(b,b+m,a[i])-b]);
scanf("%u",&q);
for(num x,y;q--;){
scanf("%u%u",&x,&y);
if(d[y]>=x)printf("%u\n",a[d[y]-1]);
else puts("OK");
}
}
return 0;
}
}}}
题意:给出一串长度为N的序列,给出M组询问,每组询问一段[l,r]区间内的重复情况,如有输出最后一组重复的数字,否者输出OK.
首先把序列里的元素离散化,对于序列里每个元素找到在它之前的最后一个与之重复的,记录下标。
根据题意,重复位置的取最靠后的,所以上述的下标都只要存个前缀最大值d[i],
对于区间[l,r],如果 d[y]>=x,就有重复,否者没有。
离散化要O(n log n),查询单次O(1)
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef unsigned num;
num a[1<<19],b[1<<19],c[1<<19],d[1<<19];
int main(){
for(num n,m,q;scanf("%u",&n)==1;putchar('\n')){
for(num i=0;i<n;++i)scanf("%u",a+i);
memcpy(b,a,n<<2);
sort(b,b+n);m=unique(b,b+n)-b;
memset(c,0,n<<2);
for(num i=0,j;i<n;c[j]=++i)
d[i+1]=max(d[i],c[j=upper_bound(b,b+m,a[i])-b]);
scanf("%u",&q);
for(num x,y;q--;){
scanf("%u%u",&x,&y);
if(d[y]>=x)printf("%u\n",a[d[y]-1]);
else puts("OK");
}
}
return 0;
}