Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define F first
- //
- //#define LOCAL
- //
- vector<pair<int,int>> g[1000001];
- class maxtree{
- public:
- int n;
- vector<int> t;
- void modify(int p, int value) {
- for (t[p += n] = value; p > 1; p >>= 1) t[p>>1] = max(t[p], t[p^1]);
- }
- int query(int l, int r) {
- int res = -1000000000;
- for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
- if (l&1) res = max(res, t[l++]);
- if (r&1) res = max(t[--r], res);
- }
- return res;
- }
- maxtree(int n):n(n),t(){
- t.resize(n << 1, -1000000000);
- }
- };
- class mintree{
- public:
- int n;
- vector<int> t;
- void modify(int p, int value) {
- for (t[p += n] = value; p > 1; p >>= 1) t[p>>1] = min(t[p], t[p^1]);
- }
- int query(int l, int r) {
- int res = 1000000000;
- for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
- if (l&1) res = min(res, t[l++]);
- if (r&1) res = min(t[--r], res);
- }
- return res;
- }
- mintree(int n):n(n),t(){
- t.resize(n << 1, 1000000000);
- }
- };
- int n, m, p;
- int main() {
- cin >> n >> m >> p;
- for (int i = 0; i < n; i++){
- for (int j = 0; j < m; j++){
- int a;
- scanf("%d", &a);
- if (a <= p){
- g[a].push_back({i + 1, j + 1});
- }
- }
- }
- for (int i = 0; i < p; i++){
- sort(g[i + 1].begin(), g[i + 1].end());
- }
- vector<maxtree> mat(n + 1, maxtree(400));
- vector<mintree> mit(n + 1, mintree(400));
- g[0].push_back({1, 1});
- vector<int> ans;
- ans.resize(g[0].size(), 0);
- mat[1].modify(1, 1);
- mit[1].modify(1, 1);
- for (int i = 1; i <= p; i++){
- vector<int> cur(g[i].size(), 1000000000);
- for (int j = 0; j < g[i].size(); j++){
- int x = g[i][j].F;
- int y = g[i][j].second;
- for (int k = 1; k <= n; k++){
- int rx = abs(k - x);
- int ry = 1000000000;
- int w;
- w = mat[k].query(1, y + 1);
- if (w != 1000000000)
- ry = min(ry, y - w);
- w = mit[k].query(y, mit[k].n);
- ry = min(ry, w - y);
- cur[j] = min(cur[j], rx + ry);
- }
- }
- for (int j = 0; j < g[i - 1].size(); j++){
- mat[g[i - 1][j].F].modify(g[i - 1][j].second, -1000000000);
- mit[g[i - 1][j].F].modify(g[i - 1][j].second, 1000000000);
- }
- for (int j = 0; j < g[i].size(); j++){
- int x = g[i][j].F;
- int y = g[i][j].second;
- mat[x].modify(y, y - cur[j]);
- mit[x].modify(y, y + cur[j]);
- }
- ans.clear();
- ans = cur;
- }
- int res = 1000000000;
- for (int i = 0; i < ans.size(); i++){
- res = min(res, ans[i]);
- }
- cout << res;
- #ifdef LOCAL
- cerr << "TIME = " << 1. * clock() / CLOCKS_PER_SEC;
- #endif
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement