Live2D

「CCO 2018 Day2」Flop Sorting 题解

link

Solution

并没有想到分治,我果然是个屑。

我们考虑分治,那么问题就是如何合并两个有序子段。不难发现,一定是前一段的后缀移到后面去,后一段的前缀移到前面去,所以我们可以两段先反转,就变成了一段连续的下降子序列,再整体反转,那么又变成了子问题,继续分治即可。

用了一点小技巧卡到了LOJ rank1。

Code

#include <bits/stdc++.h>
using namespace std;

#define Int register int
#define MAXN 5005

template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template <typename T> inline void chkmax (T &a,T b){a = max (a,b);}
template <typename T> inline void chkmin (T &a,T b){a = min (a,b);}

int n,a[MAXN],b[MAXN];

#define pii pair<int,int>
vector <pii> ans,Ans;

void fuckit (int l,int r){ans.push_back ({l,r}),swap (a[l],a[r]);}

void merge (int l,int r){
	if (l >= r) return ;
	bool flg = 1;
	for (Int i = l;i < r;++ i) if (a[i] > a[i + 1]){flg = 0;break;}
	if (flg) return ;
	int mid = l;
	while (a[mid] < a[mid + 1]) ++ mid;
	for (Int i = l;i <= r;++ i) b[i] = a[i];
	nth_element (b + l,b + mid,b + r + 1);
	int k1 = l,k2 = r;
	while (a[k1] <= b[mid]) k1 ++;
	while (a[k2] > b[mid]) k2 --;
	for (Int i = k1,j = mid;i < j;++ i,-- j) fuckit (i,j);
	for (Int i = mid + 1,j = k2;i < j;++ i,-- j) fuckit (i,j);
	for (Int i = k1,j = k2;i < j;++ i,-- j) fuckit (i,j);
	merge (l,mid),merge (mid + 1,r);
}

void divide (int l,int r){
	if (l >= r) return ;
	int mid = l + r >> 1;
	divide (l,mid),divide (mid + 1,r),merge (l,r);
}

signed main(){
	read (n);
	for (Int i = 1;i <= n;++ i) read (a[i]);
	divide (1,n),Ans = ans,ans.clear ();
	for (Int i = 1;i <= n;++ i) read (a[i]);
	divide (1,n);for (Int i = ans.size() - 1;~i;-- i) Ans.push_back (ans[i]);
	write (Ans.size()),putchar ('\n');
	for (Int i = 0;i < Ans.size();++ i) write (Ans[i].first),putchar (' '),write (Ans[i].second),putchar ('\n');
	return 0;
}
posted @ 2022-01-25 16:42  Dark_Romance  阅读(113)  评论(0编辑  收藏  举报