退役前发文了。
排序和离散都是稳定的一只$log$的做法,这里给大家介绍一种玄学复杂度的数据结构,$hash$表。
$hash$表的思想很简单,将所有对$mod$取模在一个同余类的数用链表串起来 (不要告诉我你不会链表),这样时间复杂度就依赖于$mod$大小。**理论上来说**,$mod$越大,同余类的冲突越小,跑得就快些;$mod$越小,每个同余类里聚集的数较多,跑得就慢些。我们往往需要找到那个空间和时间上的平衡点。
经实测,本题的较优$mod$是$1e6$,还有一个小优化,就是对于小于$mod$的数,单独开桶来记,但影响不大。
解决了本题的瓶颈,其他地方就不细讲了。
本题解卡了下常,拿到了$rank 1$(但估计很快就死了QwQ),$rank 2$是我们机房的一个奆奆,他的$mod$是$1e6+7$,但没有加那个小优化。
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
inline char gc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
char ch;
int bj=1;
while(!isdigit(ch=gc()))
bj=(ch=='-')?-1:1;
int res=ch^(3<<4);
while(isdigit(ch=gc()))
res=(res<<1)+(res<<3)+(ch^(3<<4));
return res*bj;
}
void printnum(int x){
if(x>9)printnum(x/10);
putchar(x%10+'0');
}
inline void print(int x,char ch){
if(x<0){
putchar('-');
x=-x;
}
printnum(x);
putchar(ch);
}
const int mod=1e6;
int to[200000],v[200000],nxt[200000],h[mod],cnt;
int n,m,a[200005],b[200005],t[mod];
int maxn1=-INF,maxn2=-INF,ans;
inline void Insert(int x){
if(x<mod){
t[x]++;
return;
}
for(int i=h[x%mod];i;i=nxt[i])
if(to[i]==x){
v[i]++;
return;
}
to[++cnt]=x;
v[cnt]=1;
nxt[cnt]=h[x%mod];
h[x%mod]=cnt;
}
inline int query(int x){
if(x<mod)return t[x];
for(int i=h[x%mod];i;i=nxt[i])
if(to[i]==x)return v[i];
return 0;
}
signed main(){
n=read();
int x;
while(n--)x=read(),Insert(x);
m=read();
for(int i=1;i<=m;i++)a[i]=read();
for(int i=1;i<=m;i++)b[i]=read();
for(int i=1;i<=m;i++){
int tmp1=query(a[i]),tmp2=query(b[i]);
if(tmp1>maxn1){
maxn1=tmp1;
maxn2=tmp2;
ans=i;
}
else if(tmp1==maxn1&&tmp2>maxn2){
maxn1=tmp1;
maxn2=tmp2;
ans=i;
}
}
print(ans,'\n');
return 0;
}
知识兔