退役前发文了。
排序和离散都是稳定的一只$log$的做法,这里给大家介绍一种玄学复杂度的数据结构,$hash$表。
$hash$表的思想很简单,将所有对$mod$取模在一个同余类的数用链表串起来 (不要告诉我你不会链表),这样时间复杂度就依赖于$mod$大小。**理论上来说**,$mod$越大,同余类的冲突越小,跑得就快些;$mod$越小,每个同余类里聚集的数较多,跑得就慢些。我们往往需要找到那个空间和时间上的平衡点。
经实测,本题的较优$mod$是$1e6$,还有一个小优化,就是对于小于$mod$的数,单独开桶来记,但影响不大。
解决了本题的瓶颈,其他地方就不细讲了。
本题解卡了下常,拿到了$rank 1$(但估计很快就死了QwQ),$rank 2$是我们机房的一个奆奆,他的$mod$是$1e6+7$,但没有加那个小优化。
#include<iostream> #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,' '); return 0; }