在做P1363幻象森林的时候,我用哈希表储存真实的x,y坐标,当使用gp_hash_table时会MLE,使用unordered_map时#6样例运行时间在1s左右,有时甚至TLE,但使用cc_hash_table虽然内存大了一点,但时间平均在0.65s左右。
但在做P1967货车运输时,我用哈希表储存倍增的LCA数据,结果是明显unordered_map在时间和空间上都是最优的,gp_hash_table不仅慢而且占内存。
这是为什么?什么影响着三种哈希表的运行状况,什么时候选哪一种哈希表才是最优选择?
#include<bits/extc++.h>
using namespace std;
#define endl '\n'
typedef int INT;
//#define int long long
inline int read(){
int x=0,y=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x*y;
}
inline void write_base(int x){
if(x>9)write_base(x/10);
putchar('0'+x%10);
}
inline void write(int x){
if(x<0)putchar('-'),x*=-1;
write_base(x);
}
using namespace __gnu_pbds;
/********************************************************/
const int N=1.5e3+1;
int n,m,Y,X;char c;bool way[N][N];
INT main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
while(cin>>n>>m){
unordered_map<int,unordered_map<int,bool>>arr;
bool flag=false;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
cin>>c,
way[i][j]=c=='#'?false:true,
c=='S'?(Y=i,X=j):0;
queue<int>qy,qx;
qy.push(Y);
qx.push(X);
arr[Y][X]=1;
#define wy(i) ((y-1+i)%n+n)%n+1
#define wx(i) ((x-1+i)%m+m)%m+1
while(qy.size()){
int &y=qy.front(),&x=qx.front();
int Wy=((y-1)%n+n)%n+1,Wx=((x-1)%m+m)%m+1;
if((Wy!=y||Wx!=x)&&arr[Wy][Wx]){
flag=true;
break;
}
if(arr[y-1][x]==0&&way[wy(-1)][Wx])
arr[y-1][x]=1,
qy.push(y-1),
qx.push(x);
if(arr[y][x+1]==0&&way[Wy][wx(1)])
arr[y][x+1]=1,
qy.push(y),
qx.push(x+1);
if(arr[y+1][x]==0&&way[wy(1)][Wx])
arr[y+1][x]=1,
qy.push(y+1),
qx.push(x);
if(arr[y][x-1]==0&&way[Wy][wx(-1)])
arr[y][x-1]=1,
qy.push(y),
qx.push(x-1);
qy.pop();
qx.pop();
}
if(flag)
cout<<"Yes";
else
cout<<"No";
cout<<endl;
}
}
#include<bits/extc++.h>
using namespace std;
#define endl '\n'
typedef int INT;
#define int long long
inline int read(){
int x=0,y=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x*y;
}
inline void write_base(int x){
if(x>9)write_base(x/10);
putchar('0'+x%10);
}
inline void write(int x){
if(x<0)putchar('-'),x*=-1;
write_base(x);
// putchar(' ');
putchar('\n');
}
using namespace __gnu_pbds;
/********************************************************/
const int N=1e4+1,M=5e4;
const int inf=1e9;
struct Side{
int a,b,w;
}side[M];
bool operator<(Side a,Side b){
if(a.w==b.w)
if(a.w==b.a)
return a.b>b.b;
else
return a.a>b.a;
return a.w>b.w;
}
int fa[N];
int find(int i){
return i==fa[i]?i:fa[i]=find(fa[i]);
}
unordered_map<int,int>son[N];int tot[N];unordered_map<int,unordered_map<int,int>>lim;
bool grand[N];
int deep[N],f[N][20],l[N][20],t[N];
bool vis[N];
int ans(int x,int y){
if(find(x)!=find(y))return -1;
if(deep[x]<deep[y])swap(x,y);
int dis=deep[x]-deep[y],z,lim=inf;
for(int i=t[x];i>=0;--i)
if((z=pow(2,i))<=dis)
dis-=z,
lim=min(lim,l[x][i]),
x=f[x][i];
if(x==y)return lim;
for(int i=t[x];f[x][0]!=f[y][0];--i)
if(f[x][i]!=f[y][i])
lim=min(lim,min(l[x][i],l[y][i])),
x=f[x][i],y=f[y][i];
return min(lim,min(l[x][0],l[y][0]));
}
INT main(){//ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
// freopen("in","r",stdin);
int n=read(),m=read();
for(int i=0;i<m;++i)
side[i].a=read(),side[i].b=read(),side[i].w=read();
sort(side,side+m);
for(int i=1;i<=n;++i)
fa[i]=i;
for(int i=0;i<m;++i){
int&a=side[i].a,&b=side[i].b;
if(find(a)!=find(b)){
int&w=side[i].w;
fa[fa[a]]=fa[b],
son[a][tot[a]++]=b,
lim[a][b]=w,
son[b][tot[b]++]=a,
lim[b][a]=w;
}
}
queue<int>q;
for(int i=1;i<=n;++i)
if(grand[find(i)]==false)
grand[fa[i]]=true,
q.push(fa[i]);
while(q.size()){
int&now=q.front();
q.pop();
t[now]=log(deep[now])/log(2);
for(int i=1;i<=t[now];++i)
f[now][i]=f[f[now][i-1]][i-1],
l[now][i]=min(l[f[now][i-1]][i-1],l[now][i-1]);
for(int i=0;i<tot[now];++i){
int&z=son[now][i];
if(vis[z]==false)
f[z][0]=now,
l[z][0]=lim[z][now],
deep[z]=deep[now]+1,
vis[now]=true,
q.push(z);
}
}
m=read();
while(m--)
write(ans(read(),read()));
}