题解 快速排序

传送门

首先发现给的快排板子是会退化的
然后注意到每个nan的相对位置是固定的
于是会从一个nan后面跑到一个nan前面的就是这个nan后面比这个nan前面的最大值小的数
注意到所有数字最终是升序排序的
树状数组维护个数即可确定每个nan的位置
最后把数字填进去就好

Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 500010
#define ll long long
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {
		if (isalpha(c)) {c=getchar(); c=getchar(); return -1;}
		else c=getchar();
	}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n;
int a[N], tmp[N];

namespace force{
	bool cmp(int a, int b) {
		if (a==-1 || b==-1) return 0;
		else return a<b;
	}
	void qsort(int* l, int* r) {
		if (l+1>=r) return ;
		int left=*l, *s=l, *t=tmp;
		for (int *p=l+1; p<r; ++p) {
			if (cmp(*p, left)) *s=*p, s++;
			else *t=*p, t++;
		}
		*s=left, s++;
		for (t--; t>=tmp; t--) *(s+(t-tmp))=*t;
		qsort(l, s-1); qsort(s, r);
	}
	void solve() {
		qsort(a+1, a+n+1);
		for (int i=1; i<=n; ++i) {
			if (a[i]==-1) printf("nan ");
			else printf("%d ", a[i]);
		}
		printf("\n");
	}
}

namespace task1{
	int ans[N], tem[N], bit[N], uni[N], usize;
	inline void add(int i) {for (; i<=usize; i+=i&-i) ++bit[i];}
	inline void del(int i) {for (; i<=usize; i+=i&-i) --bit[i];}
	inline int query(int i) {int ans=0; for (; i>0; i-=i&-i) ans+=bit[i]; return ans;}
	void solve() {
		usize=0;
		int now=1, maxn=0, tot=0, pos=1;
		for (int i=1; i<=n; ++i) ans[i]=0;
		for (int i=1; i<=n; ++i) if (a[i]>0) tem[++tot]=a[i], uni[++usize]=a[i];
		sort(uni+1, uni+usize+1);
		usize=unique(uni+1, uni+usize+1)-uni-1;
		for (int i=1; i<=n; ++i) if (a[i]>0) a[i]=lower_bound(uni+1, uni+usize+1, a[i])-uni, add(a[i]);
		for (int i=1; i<=n; ++i) {
			if (a[i]==-1) ans[now++]=-1;
			else if (a[i]>0 && a[i]<maxn) {del(a[i]); continue;}
			else {
				now+=query(a[i]-1)-query(maxn-1);
				maxn=max(maxn, a[i]);
				++now; del(a[i]);
			}
		}
		sort(tem+1, tem+tot+1);
		for (int i=1; i<=n; ++i)
			if (!ans[i]) printf("%d ", tem[pos++]);
			else printf("nan ");
		printf("\n");
	}
}

signed main()
{
	freopen("qsort.in", "r", stdin);
	freopen("qsort.out", "w", stdout);

	int T=read();
	while (T--) {
		n=read();
		for (int i=1; i<=n; ++i) a[i]=read();
		// cout<<"a: "; for (int i=1; i<=n; ++i) cout<<a[i]<<' '; cout<<endl;
		// force::solve();
		task1::solve();
	}

	return 0;
}
posted @ 2021-11-05 19:55  Administrator-09  阅读(0)  评论(0编辑  收藏  举报