結果

問題 No.1028 闇討ち
ユーザー kaagekaage
提出日時 2020-04-17 21:57:47
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 868 ms / 2,000 ms
コード長 20,725 bytes
コンパイル時間 3,380 ms
コンパイル使用メモリ 165,160 KB
実行使用メモリ 25,136 KB
最終ジャッジ日時 2024-11-14 22:20:07
合計ジャッジ時間 12,140 ms
ジャッジサーバーID
(参考情報)
judge5 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,816 KB
testcase_01 AC 2 ms
6,820 KB
testcase_02 AC 2 ms
6,820 KB
testcase_03 AC 2 ms
6,816 KB
testcase_04 AC 2 ms
6,820 KB
testcase_05 AC 2 ms
6,816 KB
testcase_06 AC 3 ms
6,816 KB
testcase_07 AC 2 ms
6,816 KB
testcase_08 AC 3 ms
6,816 KB
testcase_09 AC 30 ms
6,816 KB
testcase_10 AC 44 ms
6,820 KB
testcase_11 AC 182 ms
9,728 KB
testcase_12 AC 813 ms
24,304 KB
testcase_13 AC 804 ms
24,160 KB
testcase_14 AC 444 ms
18,620 KB
testcase_15 AC 136 ms
8,832 KB
testcase_16 AC 868 ms
24,920 KB
testcase_17 AC 864 ms
24,788 KB
testcase_18 AC 865 ms
24,988 KB
testcase_19 AC 864 ms
24,960 KB
testcase_20 AC 866 ms
24,716 KB
testcase_21 AC 865 ms
25,136 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#define _CRT_SECURE_NO_WARNINGS
#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#define rep(i, n) for(int i=0;i<(n);i++)
#define REP(i, n) for(int i=1;i<=(n);i++)
#define all(V) V.begin(),V.end()
typedef long long lint;
typedef std::pair<lint, lint> P;
constexpr int INF = INT_MAX;
constexpr lint LINF = LLONG_MAX;
constexpr double eps = 1e-9;
template<class T>
class prique :std::priority_queue<T, std::vector<T>, std::greater<T>> {};
using namespace std;
template<class T, class Alloc = std::allocator<T>>
class Vector {

	using traits = std::allocator_traits<Alloc>;

	using size_type = unsigned int;

	class iterator {

	public:

		using difference_type = int;
		using value_type = T;
		using pointer = T*;
		using reference = T&;
		using iterator_category = std::random_access_iterator_tag;

	private:

		T* p;

	public:

		iterator()noexcept :p(nullptr) {}
		iterator(Vector* base, difference_type index) noexcept :p(base->e + index) {}
		iterator(const iterator& i) :p(i.p) {}

		iterator& operator=(const iterator& i) = default;

		iterator& operator++() {
			p++;
			return *this;
		}

		iterator operator++(int) {
			iterator res = *this;
			p++;
			return res;
		}

		iterator operator+(const difference_type& x)const {
			return iterator(*this) += x;
		}

		iterator& operator+=(const difference_type& x) {
			p += x;
			return *this;
		}

		iterator& operator--() {
			p--;
			return *this;
		}

		iterator operator--(int) {
			iterator res = *this;
			p--;
			return res;
		}

		iterator operator-(const difference_type& x)const {
			return iterator(*this) -= x;
		}

		difference_type operator-(const iterator& i)const {
			return p - i.p;
		}

		iterator& operator-=(const difference_type& x) {
			p -= x;
			return *this;
		}

		reference operator*()const {
			return *p;
		}

		reference operator[](const difference_type& x)const {
			return *(p + x);
		}

		bool operator<(const iterator& i)const {
			return p < i.p;
		}

		bool operator<=(const iterator& i)const {
			return p <= i.p;
		}

		bool operator==(const iterator& i)const {
			return p == i.p;
		}

		bool operator>(const iterator& i)const {
			return p > i.p;
		}

		bool operator>=(const iterator& i)const {
			return p >= i.p;
		}

		bool operator!=(const iterator& i)const {
			return p != i.p;
		}

	};

	class const_iterator {

	public:

		using difference_type = int;
		using value_type = T;
		using pointer = const T*;
		using reference = const T&;
		using iterator_category = std::random_access_iterator_tag;

	private:

		const T* p;

	public:

		const_iterator()noexcept :p(nullptr) {}
		const_iterator(Vector* base, difference_type index) noexcept :p(base->e + index) {}
		const_iterator(const iterator& i) :p(i.p) {}
		const_iterator(const const_iterator& i) :p(i.p) {}

		const_iterator& operator=(const const_iterator& i) = default;

		const_iterator& operator++() {
			p++;
			return *this;
		}

		const_iterator operator++(int) {
			const_iterator res = *this;
			p++;
			return res;
		}

		const_iterator operator+(const difference_type& x)const {
			return const_iterator(*this) += x;
		}

		const_iterator& operator+=(const difference_type& x) {
			p += x;
			return *this;
		}

		const_iterator& operator--() {
			p--;
			return *this;
		}

		const_iterator operator--(int) {
			const_iterator res = *this;
			p--;
			return res;
		}

		const_iterator operator-(const difference_type& x)const {
			return const_iterator(*this) -= x;
		}

		difference_type operator-(const const_iterator& i)const {
			return p - i.p;
		}

		const_iterator& operator-=(const difference_type& x) {
			p -= x;
			return *this;
		}

		reference operator*()const {
			return *p;
		}

		reference operator[](const difference_type& x)const {
			return *(p + x);
		}

		bool operator<(const const_iterator& i)const {
			return p < i.p;
		}

		bool operator<=(const const_iterator& i)const {
			return p <= i.p;
		}

		bool operator==(const const_iterator& i)const {
			return p == i.p;
		}

		bool operator>(const const_iterator& i)const {
			return p > i.p;
		}

		bool operator>=(const const_iterator& i)const {
			return p >= i.p;
		}

		bool operator!=(const const_iterator& i)const {
			return p != i.p;
		}

	};

	using reverse_iterator = std::reverse_iterator<iterator>;
	using const_reverse_iterator = std::reverse_iterator<const_iterator>;

private:

	T* e;
	unsigned int length = 0, cap = 1;
	Alloc alloc;

	static_assert(std::is_same<T, typename Alloc::value_type>::value, "The allocator value type is not matched the vector value type.");
	static_assert(!std::is_const<T>::value, "This library forbids containers of const elements");

public:

	Vector() :Vector(Alloc()) {}

	explicit Vector(const Alloc& a) :alloc(a) {
		e = alloc.allocate(cap);
	}

	explicit Vector(size_type n, const Alloc& a = Alloc()) :alloc(a) {
		while (cap < n)cap *= 2;
		e = alloc.allocate(cap);
		rep(i, n)emplace_back();
	}

	explicit Vector(size_type n, const T& value, const Alloc& a = Alloc()) :alloc(a) {
		while (cap < n)cap *= 2;
		e = alloc.allocate(cap);
		rep(i, n)emplace_back(value);
	}

	template<class InputIter>
	Vector(InputIter first, InputIter last, const Alloc& a = Alloc()) :alloc(a) {
		e = alloc.allocate(cap);
		for (InputIter i = first; i != last; i++) {
			emplace_back(*i);
		}
	}

	Vector(const Vector& x, const Alloc& a = Alloc()) :alloc(a) {
		while (cap < x.length)cap *= 2;
		length = x.length;
		e = alloc.allocate(cap);
		rep(i, x.length)traits::construct(alloc, e + i, *(x.e + i));
	}

	Vector(Vector&& x, const Alloc& a = Alloc()) :alloc(a) {
		cap = x.cap;
		length = x.length;
		e = x.e;
		x.e = nullptr;
	}

	~Vector() {
		if (e != nullptr) {
			rep(i, length)traits::destroy(alloc, e + i);
			alloc.deallocate(e, cap);
		}
	}

	Vector& operator=(const Vector& x) {
		rep(i, length)traits::destroy(alloc, e + i);
		alloc.deallocate(e, cap);
		length = x.length;
		cap = 1;
		while (cap < length)cap *= 2;
		e = alloc.allocate(cap);
		rep(i, length)traits::construct(alloc, e + i, *(x.e + i));
		return *this;
	}

	Vector& operator=(Vector&& x) {
		rep(i, length)traits::destroy(alloc, e + i);
		alloc.deallocate(e, cap);
		cap = x.cap;
		length = x.length;
		e = x.e;
		x.e = nullptr;
		return *this;
	}

private:

	void extension() {
		T* e_ = alloc.allocate(cap * 2);
		rep(i, length)traits::construct(alloc, e_ + i, *(e + i));
		rep(i, length)traits::destroy(alloc, e + i);
		alloc.deallocate(e, cap);
		e = e_;
		cap *= 2;
	}

	void extension(size_type n) {
		unsigned int r = 1;
		while (cap * r < n)r *= 2;
		if (r == 1)return;
		T* e_ = alloc.allocate(cap * r);
		rep(i, length)traits::construct(alloc, e_ + i, *(e + i));
		rep(i, length)traits::destroy(alloc, e + i);
		alloc.deallocate(e, cap);
		e = e_;
		cap *= r;
	}

public:

	template<class InputIter>
	void assign(InputIter first, InputIter last) {
		unsigned int cnt = 0;
		for (InputIter i = first; i != last; i++) {
			if (cnt == cap) {
				length = std::max(length, cnt);
				extension();
			}
			traits::construct(alloc, e + cnt, *i);
			cnt++;
		}
	}

	void assign(size_type n, const T& value) {
		extension(n);
		std::fill(e, e + n, value);
	}

	template<class... Args>
	void emplace_back(Args&&... args) {
		if (length == cap)extension();
		traits::construct(alloc, e + length, std::forward<Args>(args)...);
		length++;
	}

	void push_back(const T& value) {
		emplace_back(value);
	}

	void push_back(T&& value) {
		emplace_back(std::move(value));
	}

	void pop_back() {
		traits::destroy(alloc, e + length);
		length--;
	}

	iterator erase(iterator pos) {
		const iterator res = pos;
		iterator t = pos; t++;
		for (iterator i = pos; t != end(); i++, t++) {
			*i = std::move(*t);
		}
		pop_back();
		return res;
	}

	iterator erase(iterator first, iterator last) {
		const iterator res = first;
		typename iterator::difference_type d = last - first;
		for (iterator i = first; i + d != end(); i++) {
			*i = std::move(*(i + d));
		}
		rep(i, d)pop_back();
		return res;
	}

	void swap(Vector& x) {
		std::swap(length, x.length);
		std::swap(cap, x.cap);
		std::swap(e, x.e);
	}

	void clear() {
		while (length)pop_back();
	}

	size_type size()const {
		return length;
	}

	void resize(size_type  n, const T& value = T()) {
		extension(n);
		while (n < length)pop_back();
		std::fill(e, e + n, value);
	}

	size_type capacity()const {
		return cap;
	}

	bool empty()const {
		return !length;
	}

	T& operator[](const unsigned int pos) {
		return e[pos];
	}

	T* data() {
		return e;
	}

	T& front() {
		return *e;
	}

	T& back() {
		return *(e + length - 1);
	}

	iterator begin() noexcept {
		return iterator(this, 0);
	}

	const_iterator begin()const noexcept {
		return const_iterator(this, 0);
	}

	const_iterator cbegin()const noexcept {
		return const_iterator(this, 0);
	}

	iterator rbegin()noexcept {
		return reverse_iterator(this, 0);
	}

	const_iterator rbegin()const noexcept {
		return const_reverse_iterator(this, 0);
	}

	const_iterator crbegin()const noexcept {
		return const_reverse_iterator(this, 0);
	}

	iterator end() noexcept {
		return iterator(this, length);
	}

	const_iterator end()const noexcept {
		return const_iterator(this, length);
	}

	const_iterator cend()const noexcept {
		return const_iterator(this, length);
	}

	iterator rend()noexcept {
		return reverse_iterator(this, length);
	}

	const_iterator rend()const noexcept {
		return const_reverse_iterator(this, length);
	}

	const_iterator crend()const noexcept {
		return const_reverse_iterator(this, length);
	}

};
template <class T, class U>
inline bool chmax(T& lhs, const U& rhs) {
	if (lhs < rhs) {
		lhs = rhs;
		return 1;
	}
	return 0;
}
template <class T, class U>
inline bool chmin(T& lhs, const U& rhs) {
	if (lhs > rhs) {
		lhs = rhs;
		return 1;
	}
	return 0;
}
inline lint gcd(lint a, lint b) {
	while (b) {
		lint c = a;
		a = b; b = c % b;
	}
	return a;
}
inline lint lcm(lint a, lint b) {
	return a / gcd(a, b) * b;
}
bool isprime(lint n) {
	if (n == 1)return false;
	for (int i = 2; i * i <= n; i++) {
		if (n % i == 0)return false;
	}
	return true;
}
lint mypow(lint a, lint b) {
	if (!b)return 1;
	if (b & 1)return mypow(a, b - 1) * a;
	lint memo = mypow(a, b >> 1);
	return memo * memo;
}
lint modpow(lint a, lint b, lint m) {
	if (!b)return 1;
	if (b & 1)return modpow(a, b - 1, m) * a % m;
	lint memo = modpow(a, b >> 1, m);
	return memo * memo % m;
}
template<typename T>
void printArray(std::vector<T>& vec) {
	rep(i, vec.size() - 1)std::cout << vec[i] << " ";
	std::cout << vec.back() << std::endl;
}
template<typename T>
void printArray(Vector<T>& vec) {
	rep(i, vec.size() - 1)std::cout << vec[i] << " ";
	std::cout << vec.back() << std::endl;
}
template<typename T>
void printArray(T l, T r) {
	T rprev = r;
	rprev--;
	for (T i = l; i != rprev; i++) {
		std::cout << *i << " ";
	}
	std::cout << *rprev << std::endl;
}
std::string to_string(Vector<int>& vec) {
	std::string res = "[";
	rep(i, vec.size() - 1)res += std::to_string(vec[i]) + ", ";
	res += std::to_string(vec.back()) + "]";
	return res;
}
template<typename T, typename U>
class SegTree {
protected:
	int n = 1, rank = 0;
	vector<T> node;
	vector<U> lazy;
	vector<bool> lazyflag;
	vector<int> width;
	virtual void lazyf(U&, const U&) = 0;
	virtual void updf(T&, const U&, const unsigned int&) = 0;
	void eval(int k) {
		if (!k)return;
		for (int i = rank; i > 0; i--) {
			int nk = k >> i;
			if (lazyflag[nk]) {
				updf(node[2 * nk], lazy[nk], width[2 * nk]);
				updf(node[2 * nk + 1], lazy[nk], width[2 * nk + 1]);
				if (lazyflag[2 * nk])lazyf(lazy[2 * nk], lazy[nk]);
				else lazy[2 * nk] = lazy[nk];
				if (lazyflag[2 * nk + 1])lazyf(lazy[2 * nk + 1], lazy[nk]);
				else lazy[2 * nk + 1] = lazy[nk];
				lazyflag[2 * nk] = lazyflag[2 * nk + 1] = true;
				lazyflag[nk] = false;
			}
		}
	}
public:
	SegTree(unsigned int m, T init) {
		while (n < m) {
			n *= 2;
			rank++;
		}
		node.resize(2 * n); lazy.resize(2 * n); lazyflag.resize(2 * n, false); width.resize(2 * n);
		for (int i = n; i < 2 * n; i++)node[i] = init;
		width[1] = n;
		for (int i = 2; i < 2 * n; i++) {
			width[i] = width[i >> 1] >> 1;
		}
	}
	SegTree(const vector<T>& initvec) {
		unsigned int m = initvec.size();
		while (n < m) {
			n *= 2;
			rank++;
		}
		node.resize(2 * n); lazy.resize(2 * n); lazyflag.resize(2 * n, false); width.resize(2 * n);
		for (int i = n; i < 2 * n; i++) {
			if (i - n < m)node[i] = initvec[i - n];
		}
		width[1] = n;
		for (int i = 2; i < 2 * n; i++) {
			width[i] = width[i >> 1] >> 1;
		}
	}
	virtual void update(int i, U x) {
		i += n;
		eval(i);
		updf(node[i], x, width[i]);
		if (lazyflag[i])lazyf(lazy[i], x);
		else {
			lazyflag[i] = true;
			lazy[i] = x;
		}
	}
	virtual void update(int l, int r, U x) {
		l += n; r += n;
		int nl = l, nr = r;
		while (!(nl & 1))nl >>= 1;
		while (!(nr & 1))nr >>= 1;
		nr--;
		eval(nl); eval(nr);
		while (l < r) {
			if (l & 1) {
				updf(node[l], x, width[l]);
				if (lazyflag[l])lazyf(lazy[l], x);
				else {
					lazyflag[l] = true;
					lazy[l] = x;
				}
				l++;
			}
			if (r & 1) {
				r--;
				updf(node[r], x, width[r]);
				if (lazyflag[r])lazyf(lazy[r], x);
				else {
					lazyflag[r] = true;
					lazy[r] = x;
				}
			}
			l >>= 1; r >>= 1;
		}
	}
	T operator[](const int& x) {
		eval(x + n);
		return node[x + n];
	}
	void fill(T x) {
		std::fill(all(lazyflag), false);
		std::fill(all(node), x);
	}
	void print() {
		rep(i, n)cout << operator[](i) << " ";
		cout << endl;
	}
};
class RAQ :public SegTree<lint, lint> {
	void lazyf(lint& a, const lint& b) { a += b; }
	void updf(lint& a, const lint& b, const unsigned int& width) { a += width * b; }
public:
	RAQ(int size, const lint& def = 0) :SegTree<lint, lint>(size, def) {}
	RAQ(const vector<lint>& initvec) :SegTree<lint, lint>(initvec) {}
};
class RUQ :public SegTree<lint, lint> {
	void lazyf(lint& a, const lint& b) { a = b; }
	void updf(lint& a, const lint& b, const unsigned int& width) { a = b; }
public:
	RUQ(int size, const lint& def = 0) :SegTree<lint, lint>(size, def) {}
	RUQ(const vector<lint>& initvec) :SegTree<lint, lint>(initvec) {}
};
template<typename T, typename U>
class IntervalSegTree :public SegTree<T, U> {
protected:
	using SegTree<T, U>::n;
	using SegTree<T, U>::rank;
	using SegTree<T, U>::node;
	using SegTree<T, U>::lazy;
	using SegTree<T, U>::lazyflag;
	using SegTree<T, U>::width;
	using SegTree<T, U>::eval;
	using SegTree<T, U>::lazyf;
	using SegTree<T, U>::updf;
	T nodee;
	virtual T nodef(const T&, const T&)const = 0;
public:
	IntervalSegTree(unsigned int m, T init, T nodee) :SegTree<T, U>(m, init), nodee(nodee) {}
	IntervalSegTree(T nodee, const vector<T>& initvec) :SegTree<T, U>(initvec), nodee(nodee) {}
	void update(int i, U x) {
		i += n;
		eval(i);
		updf(node[i], x, width[i]);
		if (lazyflag[i])lazyf(lazy[i], x);
		else {
			lazyflag[i] = true;
			lazy[i] = x;
		}
		while (i /= 2)node[i] = nodef(node[2 * i], node[2 * i + 1]);
	}
	void update(int l, int r, U x) {
		l += n; r += n;
		int nl = l, nr = r;
		while (!(nl & 1))nl >>= 1;
		while (!(nr & 1))nr >>= 1;
		nr--;
		eval(nl); eval(nr);
		while (l < r) {
			if (l & 1) {
				updf(node[l], x, width[l]);
				if (lazyflag[l])lazyf(lazy[l], x);
				else {
					lazyflag[l] = true;
					lazy[l] = x;
				}
				l++;
			}
			if (r & 1) {
				r--;
				updf(node[r], x, width[r]);
				if (lazyflag[r])lazyf(lazy[r], x);
				else {
					lazyflag[r] = true;
					lazy[r] = x;
				}
			}
			l >>= 1; r >>= 1;
		}
		while (nl >>= 1)node[nl] = nodef(node[2 * nl], node[2 * nl + 1]);
		while (nr >>= 1)node[nr] = nodef(node[2 * nr], node[2 * nr + 1]);
	}
	T query(int l, int r) {
		l += n; r += n;
		eval(l); eval(r - 1);
		int ls = nodee, rs = nodee;
		while (l < r) {
			if (l & 1) {
				ls = nodef(ls, node[l]);
				l++;
			}
			if (r & 1) {
				r--;
				rs = nodef(node[r], rs);
			}
			l >>= 1; r >>= 1;
		}
		return nodef(ls, rs);
	}
	T queryForAll() {
		return node[1];
	}
	void print() {
		rep(i, n)cout << SegTree<T, U>::query(i) << " ";
		cout << endl;
	}
};
class RAQRSQ :public IntervalSegTree<lint, lint> {
	lint nodef(const lint& a, const lint& b)const { return a + b; }
	void lazyf(lint& a, const lint& b) { a += b; }
	void updf(lint& a, const lint& b, const unsigned int& width) { a += width * b; }
public:
	RAQRSQ(int size, const lint& def = 0) :IntervalSegTree<lint, lint>(size, def, 0) {
		for (int i = n - 1; i > 0; i--)node[i] = nodef(node[2 * i], node[2 * i + 1]);
	}
	RAQRSQ(const vector<lint>& initvec) :IntervalSegTree<lint, lint>((lint)0, initvec) {
		for (int i = n - 1; i > 0; i--)node[i] = nodef(node[2 * i], node[2 * i + 1]);
	}
};
class RAQRMiQ :public IntervalSegTree<lint, lint> {
	lint nodef(const lint& a, const lint& b)const { return min(a, b); }
	void lazyf(lint& a, const lint& b) { a += b; }
	void updf(lint& a, const lint& b, const unsigned int& width) { a += b; }
public:
	RAQRMiQ(int size, const lint& def = 0) :IntervalSegTree<lint, lint>(size, def, LINF) {
		for (int i = n - 1; i > 0; i--)node[i] = nodef(node[2 * i], node[2 * i + 1]);
	}
	RAQRMiQ(const vector<lint>& initvec) :IntervalSegTree<lint, lint>(LINF, initvec) {
		for (int i = n - 1; i > 0; i--)node[i] = nodef(node[2 * i], node[2 * i + 1]);
	}
};
class RAQRMaQ :public IntervalSegTree<lint, lint> {
	lint nodef(const lint& a, const lint& b)const { return max(a, b); }
	void lazyf(lint& a, const lint& b) { a += b; }
	void updf(lint& a, const lint& b, const unsigned int& width) { a += b; }
public:
	RAQRMaQ(unsigned int size, const lint& def = 0) :IntervalSegTree<lint, lint>(size, def, -LINF) {
		for (int i = n - 1; i > 0; i--)node[i] = nodef(node[2 * i], node[2 * i + 1]);
	}
	RAQRMaQ(const vector<lint>& initvec) :IntervalSegTree<lint, lint>(-LINF, initvec) {
		for (int i = n - 1; i > 0; i--)node[i] = nodef(node[2 * i], node[2 * i + 1]);
	}
};
class RUQRSQ :public IntervalSegTree<lint, lint> {
	lint nodef(const lint& a, const lint& b)const { return a + b; }
	void lazyf(lint& a, const lint& b) { a = b; }
	void updf(lint& a, const lint& b, const unsigned int& width) { a = width * b; }
public:
	RUQRSQ(int size, const int& def = 0) :IntervalSegTree<lint, lint>(size, def, 0) {
		for (int i = n - 1; i > 0; i--)node[i] = nodef(node[2 * i], node[2 * i + 1]);
	}
	RUQRSQ(const vector<lint>& initvec) :IntervalSegTree<lint, lint>((lint)0, initvec) {
		for (int i = n - 1; i > 0; i--)node[i] = nodef(node[2 * i], node[2 * i + 1]);
	}
};
class RUQRMiQ :public IntervalSegTree<lint, lint> {
	lint nodef(const int& a, const int& b)const { return min(a, b); }
	void lazyf(int& a, const int& b) { a = b; }
	void updf(int& a, const int& b, const unsigned int& width) { a = b; }
public:
	RUQRMiQ(int size, const lint& def = 0) :IntervalSegTree<lint, lint>(size, def, LINF) {
		for (int i = n - 1; i > 0; i--)node[i] = nodef(node[2 * i], node[2 * i + 1]);
	}
	RUQRMiQ(const vector<lint>& initvec) :IntervalSegTree<lint, lint>(LINF, initvec) {
		for (int i = n - 1; i > 0; i--)node[i] = nodef(node[2 * i], node[2 * i + 1]);
	}
};
class RUQRMaQ :public IntervalSegTree<lint, lint> {
	lint nodef(const lint& a, const lint& b)const { return max(a, b); }
	void lazyf(lint& a, const lint& b) { a = b; }
	void updf(lint& a, const lint& b, const unsigned int& width) { a = b; }
public:
	RUQRMaQ(int size, const lint& def = 0) :IntervalSegTree<lint, lint>(size, def, -LINF) {
		for (int i = n - 1; i > 0; i--)node[i] = nodef(node[2 * i], node[2 * i + 1]);
	}
	RUQRMaQ(const vector<lint>& initvec) :IntervalSegTree<lint, lint>(-LINF, initvec) {
		for (int i = n - 1; i > 0; i--)node[i] = nodef(node[2 * i], node[2 * i + 1]);
	}
};
int n, a[1010][1010], b[2][1010];
Vector<P> home[1010];
int main() {
	std::cin >> n;
	rep(i, n) {
		rep(j, n) {
			std::cin >> a[i][j];
			home[a[i][j]].emplace_back(i, j);
		}
	}
	lint ans = 0;
	RAQRSQ st1(n), st2(n);
	REP(i, n) {
		st1.fill(0); st2.fill(0);
		for (P j : home[i]) {
			if (j.first + j.second + 1 < n)st1.update(j.first + j.second + 1, n, 1);
			if (0 <= j.first - j.second - 1)st2.update(0, j.first - j.second, 1);
			ans += j.second;
		}
		rep(j, n - 1)st1.update(j + 1, j + 2, st1[j]);
		for (int j = n - 1; j > 0; j--)st2.update(j - 1, j, st2[j]);
		int cnt = INF;
		rep(j, n)chmin(cnt, st1[j] + st2[j]);
		ans += cnt;
	}
	std::cout << ans << std::endl;
	return 0;
}
0