C++ 多维数组声明顺序
  • 板块灌水区
  • 楼主zhangxy__hp
  • 当前回复3
  • 已保存回复3
  • 发布时间2024/7/31 21:10
  • 上次更新2024/7/31 22:49:41
查看原帖
C++ 多维数组声明顺序
591008
zhangxy__hp楼主2024/7/31 21:10

以下两段代码仅在数组维度声明顺序上有区别,然而在通过题目时的用时不同

//这是较慢的代码
#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;
}

后者比前者快一倍左右。求助原因

2024/7/31 21:10
加载中...