以下两段代码仅在数组维度声明顺序上有区别,然而在通过题目时的用时不同
//这是较慢的代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5,maxb=320;
int n,m,a[maxn],ans;
int blen,st[maxb],ed[maxb];
int bel[maxn],num[maxb][maxn];
deque<int> q[maxb];
void build(){
blen=sqrt(n);
for(int i=1;i<=blen;i++){
st[i]=ed[i-1]+1;
ed[i]=ed[i-1]+blen;
for(int j=st[i];j<=ed[i];j++){
bel[j]=i;
num[i][a[j]]++;
q[i].push_back(a[j]);
}
}
if(ed[blen]<n){
blen++;
st[blen]=ed[blen-1]+1;
ed[blen]=n;
for(int i=st[blen];i<=n;i++){
bel[i]=blen;
num[blen][a[i]]++;
q[blen].push_back(a[i]);
}
}
return ;
}
void upd(int l,int r){
int pl=bel[l],pr=bel[r];
if(pl==pr){
int tmp=q[pl][r-st[pl]];
q[pl].erase(q[pl].begin()+r-st[pl]);
q[pl].insert(q[pl].begin()+l-st[pl],tmp);
return ;
}
int tmp=q[pr][r-st[pr]];
q[pr].erase(q[pr].begin()+r-st[pr]);
num[pr][tmp]--;
q[pl].insert(q[pl].begin()+l-st[pl],tmp);
num[pl][tmp]++;
for(int i=pl;i<pr;i++){
int v=q[i].back();
q[i].pop_back();
num[i][v]--;
q[i+1].push_front(v);
num[i+1][v]++;
}
return ;
}
int query(int l,int r,int k){
int pl=bel[l],pr=bel[r],res=0;
if(pl==pr){
for(int i=l;i<=r;i++)
if(q[pl][i-st[pl]]==k)res++;
return res;
}
for(int i=pl+1;i<pr;i++) res+=num[i][k];
for(int i=l;i<=ed[pl];i++)
if(q[pl][i-st[pl]]==k)res++;
for(int i=st[pr];i<=r;i++)
if(q[pr][i-st[pr]]==k)res++;
return res;
}
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
build();
cin>>m;
while(m--){
int opt,l,r,k;
cin>>opt;
switch(opt){
case 1:{
cin>>l>>r;
l=(l+ans-1)%n+1;
r=(r+ans-1)%n+1;
if(l>r) swap(l,r);
upd(l,r);
break;
}default:{
cin>>l>>r>>k;
l=(l+ans-1)%n+1;
r=(r+ans-1)%n+1;
if(l>r) swap(l,r);
k=(k+ans-1)%n+1;
ans=query(l,r,k);
cout<<ans<<"\n";
break;
}
}
}
return 0;
}
//这是较快的代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5,maxb=320;
int n,m,a[maxn],ans;
int blen,st[maxb],ed[maxb];
int bel[maxn],num[maxn][maxb];
deque<int> q[maxb];
void build(){
blen=sqrt(n);
for(int i=1;i<=blen;i++){
st[i]=ed[i-1]+1;
ed[i]=ed[i-1]+blen;
for(int j=st[i];j<=ed[i];j++){
bel[j]=i;
num[a[j]][i]++;
q[i].push_back(a[j]);
}
}
if(ed[blen]<n){
blen++;
st[blen]=ed[blen-1]+1;
ed[blen]=n;
for(int i=st[blen];i<=n;i++){
bel[i]=blen;
num[a[i]][blen]++;
q[blen].push_back(a[i]);
}
}
return ;
}
void upd(int l,int r){
int pl=bel[l],pr=bel[r];
if(pl==pr){
int tmp=q[pl][r-st[pl]];
q[pl].erase(q[pl].begin()+r-st[pl]);
q[pl].insert(q[pl].begin()+l-st[pl],tmp);
return ;
}
int tmp=q[pr][r-st[pr]];
q[pr].erase(q[pr].begin()+r-st[pr]);
num[tmp][pr]--;
q[pl].insert(q[pl].begin()+l-st[pl],tmp);
num[tmp][pl]++;
for(int i=pl;i<pr;i++){
int v=q[i].back();
q[i].pop_back();
num[v][i]--;
q[i+1].push_front(v);
num[v][i+1]++;
}
return ;
}
int query(int l,int r,int k){
int pl=bel[l],pr=bel[r],res=0;
if(pl==pr){
for(int i=l;i<=r;i++)
if(q[pl][i-st[pl]]==k)res++;
return res;
}
for(int i=pl+1;i<pr;i++) res+=num[k][i];
for(int i=l;i<=ed[pl];i++)
if(q[pl][i-st[pl]]==k)res++;
for(int i=st[pr];i<=r;i++)
if(q[pr][i-st[pr]]==k)res++;
return res;
}
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
build();
cin>>m;
while(m--){
int opt,l,r,k;
cin>>opt;
switch(opt){
case 1:{
cin>>l>>r;
l=(l+ans-1)%n+1;
r=(r+ans-1)%n+1;
if(l>r) swap(l,r);
upd(l,r);
break;
}default:{
cin>>l>>r>>k;
l=(l+ans-1)%n+1;
r=(r+ans-1)%n+1;
if(l>r) swap(l,r);
k=(k+ans-1)%n+1;
ans=query(l,r,k);
cout<<ans<<"\n";
break;
}
}
}
return 0;
}
后者比前者快一倍左右。求助原因