快排常数巨大,1.2e6操作求改进
查看原帖
快排常数巨大,1.2e6操作求改进
386892
REMAC楼主2023/7/13 20:22
#include <bits/stdc++.h>
using namespace std;

const int maxn=1e5;

int bot[3];//底下 
int top[3];//顶 

int p[3][maxn];

string ans;
int tot;
void mv(int a,int b) {
	tot++;
	ans+=string()+char('A'+a)+" "+char('A'+b)+"\n";
	top[a]--;
	top[b]++;
	p[b][top[b]]=p[a][top[a]+1];
}

pair <int,int> C(int a) { //辅助柱 
	switch(a) {
		case 0: return make_pair(1,2);
		case 1: return make_pair(0,2);
		case 2: return make_pair(0,1);
	}
}

int tmp[maxn];

void work(int cur,bool inv) {
	auto ord=inv?[](int a,int b)->bool{return a<b;}:[](int a,int b)->bool{return a>b;}; //比较函数 
	if(top[cur]-bot[cur]<2) return;
	bool flag=1;
	for(int i=bot[cur]+2;i<=top[cur];i++) flag&=ord(p[cur][i-1],p[cur][i]);
	if(flag) return; //有序不排 
	for(int i=1;i<=top[cur]-bot[cur];i++) tmp[i]=p[cur][i+bot[cur]];
	sort(tmp+1,tmp+1+(top[cur]-bot[cur]));
	int guard=tmp[(top[cur]-bot[cur])/2]; //中位哨兵 
	int t1,t2,br=bot[cur];
	t1=C(cur).first,t2=C(cur).second;
	while(top[cur]!=bot[cur]) {
		if((p[cur][top[cur]]<=guard)^!inv) mv(cur,t1);
		else mv(cur,t2);
	}
	int rec[3];//保护现场 
	rec[0]=bot[0];
	rec[1]=bot[1];
	rec[2]=bot[2];
	
	bot[cur]=top[cur];
	bot[t2]=top[t2];
	work(t1,!inv);
	bot[cur]=rec[cur];
	bot[t2]=rec[t2];
	
	bot[cur]=top[cur];
	bot[t1]=top[t1];
	work(t2,!inv);
	bot[cur]=rec[cur];
	bot[t1]=rec[t1];
	//合并 
	while(top[t1]!=bot[t1]) mv(t1,cur);
	while(top[t2]!=bot[t2]) mv(t2,cur);
}

int c[maxn];


int main() {
	int n;
	cin>>n;
	for(int i=n;i>=1;i--) cin>>p[0][i];
	top[0]=n;
	for(int i=1;i<=n;i++) mv(0,2);
	work(2,0);
	cout<<tot<<endl;
//	bool flag=1;
//	for(int i=2;i<=n;i++) flag&=p[2][i-1]>p[2][i];
// 	cout<<(flag?"Okay.":"Wrong!!");
//		for(int i=0;i<3;i++) {
//		for(int j=1;j<=top[i];j++) cout<<p[i][j]<<' ';
//		cout<<endl;
//	}
	cout<<ans;
}

当n=40000时大约在1268928操作左右。

2023/7/13 20:22
加载中...