例如,在今天我在帮同学调试 P5445 的过程中,发现以下代码在洛谷获得 90pts(MLE),而在我们学校自己搭建的 oj 上可以 AC,使用的是 cc_hash_table:

#include<iostream>
#include<algorithm>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
const int N=3e5+5;
string s,op;
int n,q,pre,suf;
struct Seg{
int lb[N*4],rb[N*4];
void build(int u,int l,int r){
if(l==r){
lb[u]=rb[u]=l;
return;
}
int mid=(l+r)>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
}
void pushdown(int u){
if(lb[u])lb[u<<1]=lb[u],lb[u<<1|1]=lb[u],lb[u]=0;
if(rb[u])rb[u<<1]=rb[u],rb[u<<1|1]=rb[u],rb[u]=0;
}
int qry(int u,int l,int r,int k,int tp){
if(l==r)
return tp?rb[u]:lb[u];
pushdown(u);
int mid=(l+r)>>1;
if(k<=mid)return qry(u<<1,l,mid,k,tp);
else return qry(u<<1|1,mid+1,r,k,tp);
}
void mdf(int u,int l,int r,int L,int R,int tp,int x){
if(L<=l&&r<=R){
tp?(rb[u]=x):(lb[u]=x);
return;
}
pushdown(u);
int mid=(l+r)>>1;
if(L<=mid)mdf(u<<1,l,mid,L,R,tp,x);
if(R>mid)mdf(u<<1|1,mid+1,r,L,R,tp,x);
}
}T;
struct Bit{
cc_hash_table<int,int> val[N];
void mdf(int x,int y,int k){
for(int i=x;i<=n+1;i+=i&(-i))
for(int j=y;j<=n+1;j+=j&(-j))
val[i][j]+=k;
}
int qry(int x,int y){
int res=0;
for(int i=x;i;i-=i&(-i))
for(int j=y;j;j-=j&(-j))
if(val[i].find(j)!=val[i].end())
res+=val[i][j];
return res;
}
}bit;
void mdf(int a,int c,int b,int d,int x){
bit.mdf(a,b,x),bit.mdf(c+1,b,-x),bit.mdf(a,d+1,-x),bit.mdf(c+1,d+1,x);
}
void del(int x,int t){
int l=T.qry(1,1,n+1,x,0),r=T.qry(1,1,n+1,x+1,1);
T.mdf(1,1,n+1,l,x,1,x),T.mdf(1,1,n+1,x+1,r,0,x+1);
mdf(l,x,x+1,r,t-q);
s[x-1]='0';
}
void add(int x,int t){
int l=T.qry(1,1,n+1,x,0),r=T.qry(1,1,n+1,x+1,1);
T.mdf(1,1,n+1,l,x,1,r),T.mdf(1,1,n+1,x+1,r,0,l);
mdf(l,x,x+1,r,q-t);
s[x-1]='1';
}
int main(){
// freopen("light.in","r",stdin);
// freopen("light.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>q>>s;
T.build(1,1,n+1);
for(int i=0;i<(int)s.size();i++){
if(s[i]=='1')add(i+1,0);
}
for(int i=1,x,a,b;i<=q;i++){
cin>>op;
if(op=="toggle"){
cin>>x;
if(s[x-1]=='1')del(x,i);
else add(x,i);
}else{
cin>>a>>b;
int ans=bit.qry(a,b);
if(T.qry(1,1,n+1,a,1)>=b)ans-=q-i;
cout<<ans<<'\n';
}
}
return 0;
}
如果我使用 unordered_map,它将直接通过两边的测试数据:

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5;
string s,op;
int n,q,pre,suf;
struct Seg{
int lb[N*4],rb[N*4];
void build(int u,int l,int r){
if(l==r){
lb[u]=rb[u]=l;
return;
}
int mid=(l+r)>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
}
void pushdown(int u){
if(lb[u])lb[u<<1]=lb[u],lb[u<<1|1]=lb[u],lb[u]=0;
if(rb[u])rb[u<<1]=rb[u],rb[u<<1|1]=rb[u],rb[u]=0;
}
int qry(int u,int l,int r,int k,int tp){
if(l==r)
return tp?rb[u]:lb[u];
pushdown(u);
int mid=(l+r)>>1;
if(k<=mid)return qry(u<<1,l,mid,k,tp);
else return qry(u<<1|1,mid+1,r,k,tp);
}
void mdf(int u,int l,int r,int L,int R,int tp,int x){
if(L<=l&&r<=R){
tp?(rb[u]=x):(lb[u]=x);
return;
}
pushdown(u);
int mid=(l+r)>>1;
if(L<=mid)mdf(u<<1,l,mid,L,R,tp,x);
if(R>mid)mdf(u<<1|1,mid+1,r,L,R,tp,x);
}
}T;
struct Bit{
unordered_map<int,int> val[N];
void mdf(int x,int y,int k){
for(int i=x;i<=n+1;i+=i&(-i))
for(int j=y;j<=n+1;j+=j&(-j))
val[i][j]+=k;
}
int qry(int x,int y){
int res=0;
for(int i=x;i;i-=i&(-i))
for(int j=y;j;j-=j&(-j))
if(val[i].find(j)!=val[i].end())
res+=val[i][j];
return res;
}
}bit;
void mdf(int a,int c,int b,int d,int x){
bit.mdf(a,b,x),bit.mdf(c+1,b,-x),bit.mdf(a,d+1,-x),bit.mdf(c+1,d+1,x);
}
void del(int x,int t){
int l=T.qry(1,1,n+1,x,0),r=T.qry(1,1,n+1,x+1,1);
T.mdf(1,1,n+1,l,x,1,x),T.mdf(1,1,n+1,x+1,r,0,x+1);
mdf(l,x,x+1,r,t-q);
s[x-1]='0';
}
void add(int x,int t){
int l=T.qry(1,1,n+1,x,0),r=T.qry(1,1,n+1,x+1,1);
T.mdf(1,1,n+1,l,x,1,r),T.mdf(1,1,n+1,x+1,r,0,l);
mdf(l,x,x+1,r,q-t);
s[x-1]='1';
}
int main(){
// freopen("light.in","r",stdin);
// freopen("light.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>q>>s;
T.build(1,1,n+1);
for(int i=0;i<(int)s.size();i++){
if(s[i]=='1')add(i+1,0);
}
for(int i=1,x,a,b;i<=q;i++){
cin>>op;
if(op=="toggle"){
cin>>x;
if(s[x-1]=='1')del(x,i);
else add(x,i);
}else{
cin>>a>>b;
int ans=bit.qry(a,b);
if(T.qry(1,1,n+1,a,1)>=b)ans-=q-i;
cout<<ans<<'\n';
}
}
return 0;
}
在当我使用 gp_hash_table 时,我在学校的 oj 上如何卡常都卡不过去,无法通过(TLE),但是在洛谷直接过了。

(这里就不赋代码了,直接把 cc_hash_table 的那份改成 gp_hash_table 就为我所使用的代码)
因为我不太懂 pbds 或者说 STL 的东西,按理来说 gp_hash_table 会更快,但是却在我校 oj 中出现明显的效率差异
所以求问以下问题: