Loading...

[题解] APIO 2022 Practice T3 Treasure

前言

摆烂了,正好在 APIO 试机练习赛看到这道挺水但是挺有意思的题,做完写个题解。

题意

通信题,实现两个函数:

std::vector<int> encode(std::vector<int> x,std::vector<int> y)
std::vector<int> decode(std::vector<int> e)

其中 encode 实现把给出的 \(n (n \le 4\times 10^4)\) 个点编码成一个长度不超过 \(3n\) 的值域为 \([0,2 \times 10 ^ 9]\) 的整型数组,数组被打乱后传入 decode,返回一个长度 \(2n\) 的数组,为原来的点的坐标,形如 \(x_i,y_i,x_j,y_j,\cdots,x_k,y_k\),不要求点的顺序与原来一致 。

\(n \le 4 \times 10^4,0 \le x,y \le 5 \times 10^8\)

解法

首先长度 \(3n\),根据我几乎没有的信息熵 知识 直觉猜测其中 \(\mathcal{O}(n)\) 是给 \(x\) 的,\(\mathcal{O}(n)\) 是给 \(y\) 的,剩下大约 \(n\) 是给一个索引的。

然后因为会被打乱,需要保证生成的序列是一个递增的形式,这样直接排序就能恢复原来的序列。

那么就首先把所有节点按照 \(x,y\) 双关键字排序,把 \(x_i\) 原样加入编码数组,占用长度 \(n\)

\(y\) 排序后去重,把 \(y_i + 5 \times 10^8\) 加入编码数组,保证排在 \(x\) 之后。

最后把 \(x_i\) 对应的 \(y\) 离散化后的值加上 \(10^9 + 2\) 加入编码数组,但是这时候我们发现不能保证位置是递增的,于是我们改为加入前缀和,解码时差分即可。

值域大概是一个 \(1.8 \times 10^9\),随便过。

代码

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
#include "treasure.h"

#define rep(a,b,c) for(int a = (b);a <= (c);++a)
#define repb(a,b,c) for(int a = (b);a >= (c);--a)
#define repl(a,b,c) for(int a = (b);a < (c);++a)
#define repr(a,b,c) for(int  a = (b);a > (c);--a)
#define repg(a,b) for(int a = head[b];~a;a = e[a].nxt)
#define mems(a,b) memset(a,b,sizeof(a))
#define O(x) std::cerr << #x << ':' << x << std::endl;

using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128;
using u128 = __uint128_t;
using f32 = float;
using f64 = double;
using f80 = long double;
using pii = std::pair<int,int>;

constexpr int N = 40000;
constexpr int C = 500000001;
constexpr int D = 1000000002;

std::vector<int> encode(std::vector<int> x,std::vector<int> y) {
	std::vector<pii> pt;
	std::vector<int> r,d;
	repl(i,0,(int)x.size()) pt.emplace_back(x[i],y[i]);
	std::sort(pt.begin(),pt.end());
	std::sort(x.begin(),x.end());
	std::sort(y.begin(),y.end());
	y.erase(std::unique(y.begin(),y.end()),y.end());
	repl(i,0,(int)x.size()) r.emplace_back(x[i]);
	repl(i,0,(int)y.size()) r.emplace_back(y[i] + C);
	for(auto p : pt) {
		int py = std::lower_bound(y.begin(),y.end(),p.second) - y.begin();
		d.emplace_back(py);
	}
	int sum = 0;
	for(auto dis : d) {
		sum += dis;
		r.emplace_back(sum + D);
	}
	return r;
}

std::vector<int> decode(std::vector<int> e) {
	std::sort(e.begin(),e.end());
	std::vector<int> px,py,pd,r;
	int n = 0;
	while(e[n] <= 5e8)
		px.emplace_back(e[n++]);
	int ny = n;
	while(e[ny] <= 1e9 + 1)
		py.emplace_back(e[ny++]);
	pd.emplace_back(e[ny] - D);
	repl(i,1,n)
		pd.emplace_back(e[ny + i] - e[ny + i - 1]);
	repl(i,0,n) {
		int x = px[i];
		int y = py[pd[i]];
		r.emplace_back(x);
		r.emplace_back(y - C);
	}
	return r;
}
posted @ 2022-05-23 11:35  AstatineAi  阅读(167)  评论(0)    收藏  举报