Loading

【题解】[JOI Open 2021] Monster Game

麻了,并不知道自适应交互器怎么实现的/kk,但是题目还是可以想的(

最开始想直接 std::sort 一遍,事实上这个 \(<\) 没有传递性,会返回各种奇奇怪怪的结果。

事实上这是非常神仙的结论题。

结论:直接归并排序之后的数组满足 \(a_i - a_{i + 1} \le 1\)​。

并不知道出题人怎么想到这个神奇的性质,但知道结论后,我们不难直接递归归纳证明。

拥有这个性质的数组并不少见,因为换一种表述,初始数组为 \(0\sim N-1\),然后将原数组分为若干段,每一段取反即可。

所以我们知道前 \(i\) 段的端点,就可以知道第 \(i + 1\) 段的断点。问题转化为找到 \(0\) 的位置。

由于 \(0\) 只会比 \(1\) 小,所以在归并时候,一直在往前跳,感性理解一下。所以排序后 \(0\) 的位置在前 \(\log N\) 个之内。

\(\log N\) 很小,我们直接用 \(N^2\) 算法求出 \(0\) 的位置即可。

/*
    Author : SharpnessV
    Right Output ! & Accepted !
*/
#include<bits/stdc++.h>
#include"monster.h"
//#define int long long
using namespace std;

#define rep(i, a, b) for(int i = (a);i <= (b);i++)
#define pre(i, a, b) for(int i = (a);i >= (b);i--)
#define rp(i, a) for(int i = 1; i <= (a); i++)
#define pr(i, a) for(int i = (a); i >= 1; i--)
#define go(i, x) for(auto i : x)

#define pb push_back


std::vector<int> a, b, c;

void msort(int l,int r){
	if(l == r)return ;
	int mid = (l + r) >> 1, j = l;
	msort(l, mid), msort(mid + 1, r);
	b.clear();
	rep(i, mid + 1, r){
		while(j <= mid && !Query(a[j], a[i]))b.pb(a[j ++]);
		b.pb(a[i]);
	}
	while(j <= mid)b.pb(a[j ++]);
	rep(i, l, r)a[i] = b[i - l];
}
int cnt[20];
std::vector<int> Solve(int N) {
	
	a.resize(N), b.resize(N), c.resize(N);
  	rp(i, N)a[i - 1] = c[i - 1] = i - 1;
	msort(0, N - 1);
	int n = std::min(20, N);
	
	rep(i, 0, n - 1)rep(j, i + 1, n - 1)
		if(Query(a[i], a[j]))cnt[i]++;
		else cnt[j]++;
	int ed = ~0, pre = 0;
	rep(i, 0, n - 1)if(!cnt[i])ed = i;
	if(-1 == ed){
		int p = 0, q = 0;
		rep(i, 0, n - 1)if(1 == cnt[i])q = i, std::swap(p, q);
		if(Query(a[p], a[q]))ed = p;else ed = q;
	}
	
	//cout<< "ss "<<ed << endl; 
	//rep(i, 0, N - 1)printf("%d ",a[i]);putchar('\n');
	reverse(c.begin(), c.begin() + ed + 1);
	rep(k, ed + 1, N - 1){
		if(Query(a[pre], a[k]))
			reverse(c.begin() + ed + 1, c.begin() + k + 1), pre = ed + 1, ed = k;//, cout << "ww " << k <<endl;
	}
	//rep(i, 0, N - 1)printf("%d ",c[i]);putchar('\n');
	rep(i, 0, N - 1)b[a[i]] = c[i];
	//rep(i, 0, N - 1)printf("%d ",b[i]);putchar('\n');
	return b;
}
/*
g++ monster.cpp grader.cpp -o cur -std=c++14
*/
posted @ 2021-08-24 22:34  7KByte  阅读(179)  评论(0编辑  收藏  举报