Submission #834281

# Submission time Handle Problem Language Result Execution time Memory
834281 2023-08-22T12:36:29 Z Josia Ancient Books (IOI17_books) C++17
Compilation error
0 ms 0 KB
#include "books.h"
#include <bits/stdc++.h>

using namespace std;

#define int int64_t


vector<int> p;
int s;
int n;
int ret;

struct cycle {
	int left=1e9, right=-1e9;
	set<int> points;
};
bool CycleLess(cycle &a, cycle &b) {
	return pair<int, int>{a.left, a.right} < pair<int, int>{b.left, b.right};
}
bool merge(cycle &a, cycle &b) {			// a<-b
	if (!(b.left < a.left && b.right < a.right && b.right > a.left)) return 0;

	// if (a.points.size() < b.points.size()) swap(a, b);

	a.left = b.left;
	for (int i: b.points) a.points.insert(i);
	
	return 1;
}
bool contains(cycle &a, cycle &b) {
	return (a.left <= b.left && b.right <= a.right);
}



vector<bool> vis;
cycle getCycle(int v) {
	// assert(vis[v]==0);

	cycle res;

	while (vis[v] == 0) {
		vis[v] = 1;
		res.left = min(res.left, v);
		res.right = max(res.right, v);
		res.points.insert(v);

		ret += abs(v-p[v]);
		v = p[v];
	}
	return res;
}

vector<cycle> mergedCycles;
vector<int> parents;

int dfs(int v, int par) {
	parents[v] = par;
	int w = v+1;

	while (w<(int)mergedCycles.size() && contains(mergedCycles[v], mergedCycles[w])) {
		w = dfs(w, v);
	}
	return w;
}


void solve() {
	vis.assign(n, 0);

	vector<cycle> cycles;

	if (p[s]==s) cycles.push_back({s, s, {s}});
	int globLeft=s, globRight=s;

	for (int i = 0; i<n; i++) {
		if (vis[i]) continue;
		cycles.push_back(getCycle(i));
		if (cycles.back().left == cycles.back().right) cycles.pop_back();
		else {
			globLeft = min(globLeft, cycles.back().left);
			globRight = max(globRight, cycles.back().right);
		}
	}

	sort(cycles.begin(), cycles.end(), CycleLess);

	vector<int> inds;

	set<pair<int, int>> pq;

	for (int i = 0; i<(int)(cycles.size()); i++) {
		auto pointer = pq.lower_bound({cycles[i].left, -1e9});
		vector<pair<int, int>> toErase, toInsert;
		while (pointer != pq.end() && (*pointer).first <= cycles[i].right) {
			toErase.push_back(*pointer);

			merge(cycles[i], cycles[(*pointer).second]);

			pointer++;
		}

		for (auto i: toErase) pq.erase(i);
		pq.insert({cycles[i].right, i});
	}
	
	for (auto i: pq) inds.push_back(i.second);
	sort(inds.begin(), inds.end());
	


	mergedCycles.clear();
	for (int i: inds) mergedCycles.push_back(cycles[i]);

	// assert(is_sorted(mergedCycles.begin(), mergedCycles.end(), CycleLess));

	sort(mergedCycles.begin(), mergedCycles.end());

	parents.assign(mergedCycles.size(), -1);
	for (int i = 0; i<(int)mergedCycles.size(); i=dfs(i, -1));


	int pos=-1;
	for (int i = 0; i<(int)mergedCycles.size(); i++) {
		if (mergedCycles[i].points.count(s)) pos = i;
	}
	// assert(pos!=-1);



	vector<pair<int, int>> jump(n);

	for (int i = 0; i<n; i++) {
		jump[i]={i, i};
	}

	for (int i: inds) {
		for (int j: cycles[i].points) {
			jump[j].first = cycles[i].left;
			jump[j].second = cycles[i].right;
		}
	}


	
	while (parents[pos] != -1) {
		cycle elem = mergedCycles[pos];
		cycle parent = mergedCycles[parents[pos]];

		auto goRightPoint = parent.points.lower_bound(elem.left);
		auto goLeftPoint = prev(parent.points.upper_bound(elem.right));

		// assert(parent.points.lower_bound(elem.left) != parent.points.end());
		// assert(parent.points.upper_bound(elem.right) != parent.points.begin());

		// let's hope it'll not go wrong.

		int right = *goRightPoint, left = *goLeftPoint;

		// if (right <= elem.right || left >= elem.left) {
		// 	pos = parents[pos];
		// 	continue;
		// }

		int costRight = 0;
		int posToRight = elem.right;
		while (posToRight < right) {
			costRight++;
			posToRight = jump[posToRight+1].second;
		}

		int costLeft = 0;
		int posToLeft = elem.left;
		while (posToLeft > left) {
			costLeft++;
			posToLeft = jump[posToLeft-1].first;
		}

		ret += 2*min(costLeft, costRight);

		pos = parents[pos];
	}

	vector<int> noParent;

	for (int i = 0; i<(int)parents.size(); i++) {
		if (parents[i] == -1) noParent.push_back(i);
	}

	for (int i = 0; i<(int)(noParent.size())-1; i++) {
		assert(mergedCycles[noParent[i+1]].left>mergedCycles[noParent[i]].right);
		ret+=2*(mergedCycles[noParent[i+1]].left-mergedCycles[noParent[i]].right);
	}
}


long long minimum_walk(vector<signed> _p, signed _s) {
	ret = 0;
	s = _s;
	n = _p.size();
	p.resize(n); for (int i = 0; i<n; i++) p[i] = _p[i];

	
	solve();


	return ret;
}

Compilation message

In file included from /usr/include/c++/10/bits/stl_algobase.h:71,
                 from /usr/include/c++/10/vector:60,
                 from books.h:1,
                 from books.cpp:1:
/usr/include/c++/10/bits/predefined_ops.h: In instantiation of 'constexpr bool __gnu_cxx::__ops::_Iter_less_iter::operator()(_Iterator1, _Iterator2) const [with _Iterator1 = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Iterator2 = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >]':
/usr/include/c++/10/bits/stl_algo.h:82:17:   required from 'void std::__move_median_to_first(_Iterator, _Iterator, _Iterator, _Iterator, _Compare) [with _Iterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/include/c++/10/bits/stl_algo.h:1924:34:   required from '_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/include/c++/10/bits/stl_algo.h:1958:38:   required from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Size = long int; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/include/c++/10/bits/stl_algo.h:1974:25:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/include/c++/10/bits/stl_algo.h:4859:18:   required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >]'
books.cpp:118:47:   required from here
/usr/include/c++/10/bits/predefined_ops.h:43:23: error: no match for 'operator<' (operand types are 'cycle' and 'cycle')
   43 |       { return *__it1 < *__it2; }
      |                ~~~~~~~^~~~~~~~
In file included from /usr/include/c++/10/bits/stl_algobase.h:67,
                 from /usr/include/c++/10/vector:60,
                 from books.h:1,
                 from books.cpp:1:
/usr/include/c++/10/bits/stl_iterator.h:1096:5: note: candidate: 'template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)'
 1096 |     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/10/bits/stl_iterator.h:1096:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/10/bits/stl_algobase.h:71,
                 from /usr/include/c++/10/vector:60,
                 from books.h:1,
                 from books.cpp:1:
/usr/include/c++/10/bits/predefined_ops.h:43:23: note:   'cycle' is not derived from 'const __gnu_cxx::__normal_iterator<_IteratorL, _Container>'
   43 |       { return *__it1 < *__it2; }
      |                ~~~~~~~^~~~~~~~
In file included from /usr/include/c++/10/bits/stl_algobase.h:67,
                 from /usr/include/c++/10/vector:60,
                 from books.h:1,
                 from books.cpp:1:
/usr/include/c++/10/bits/stl_iterator.h:1104:5: note: candidate: 'template<class _Iterator, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_Iterator, _Container>&, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)'
 1104 |     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/10/bits/stl_iterator.h:1104:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/10/bits/stl_algobase.h:71,
                 from /usr/include/c++/10/vector:60,
                 from books.h:1,
                 from books.cpp:1:
/usr/include/c++/10/bits/predefined_ops.h:43:23: note:   'cycle' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
   43 |       { return *__it1 < *__it2; }
      |                ~~~~~~~^~~~~~~~
/usr/include/c++/10/bits/predefined_ops.h: In instantiation of 'bool __gnu_cxx::__ops::_Val_less_iter::operator()(_Value&, _Iterator) const [with _Value = cycle; _Iterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >]':
/usr/include/c++/10/bits/stl_algo.h:1826:20:   required from 'void std::__unguarded_linear_insert(_RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Compare = __gnu_cxx::__ops::_Val_less_iter]'
/usr/include/c++/10/bits/stl_algo.h:1854:36:   required from 'void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/include/c++/10/bits/stl_algo.h:1886:25:   required from 'void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/include/c++/10/bits/stl_algo.h:1977:31:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/include/c++/10/bits/stl_algo.h:4859:18:   required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >]'
books.cpp:118:47:   required from here
/usr/include/c++/10/bits/predefined_ops.h:96:22: error: no match for 'operator<' (operand types are 'cycle' and 'cycle')
   96 |       { return __val < *__it; }
      |                ~~~~~~^~~~~~~
In file included from /usr/include/c++/10/bits/stl_algobase.h:67,
                 from /usr/include/c++/10/vector:60,
                 from books.h:1,
                 from books.cpp:1:
/usr/include/c++/10/bits/stl_iterator.h:1096:5: note: candidate: 'template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)'
 1096 |     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/10/bits/stl_iterator.h:1096:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/10/bits/stl_algobase.h:71,
                 from /usr/include/c++/10/vector:60,
                 from books.h:1,
                 from books.cpp:1:
/usr/include/c++/10/bits/predefined_ops.h:96:22: note:   'cycle' is not derived from 'const __gnu_cxx::__normal_iterator<_IteratorL, _Container>'
   96 |       { return __val < *__it; }
      |                ~~~~~~^~~~~~~
In file included from /usr/include/c++/10/bits/stl_algobase.h:67,
                 from /usr/include/c++/10/vector:60,
                 from books.h:1,
                 from books.cpp:1:
/usr/include/c++/10/bits/stl_iterator.h:1104:5: note: candidate: 'template<class _Iterator, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_Iterator, _Container>&, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)'
 1104 |     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/10/bits/stl_iterator.h:1104:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/10/bits/stl_algobase.h:71,
                 from /usr/include/c++/10/vector:60,
                 from books.h:1,
                 from books.cpp:1:
/usr/include/c++/10/bits/predefined_ops.h:96:22: note:   'cycle' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
   96 |       { return __val < *__it; }
      |                ~~~~~~^~~~~~~
/usr/include/c++/10/bits/predefined_ops.h: In instantiation of 'bool __gnu_cxx::__ops::_Iter_less_val::operator()(_Iterator, _Value&) const [with _Iterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Value = cycle]':
/usr/include/c++/10/bits/stl_heap.h:139:48:   required from 'void std::__push_heap(_RandomAccessIterator, _Distance, _Distance, _Tp, _Compare&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Distance = long int; _Tp = cycle; _Compare = __gnu_cxx::__ops::_Iter_less_val]'
/usr/include/c++/10/bits/stl_heap.h:246:23:   required from 'void std::__adjust_heap(_RandomAccessIterator, _Distance, _Distance, _Tp, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Distance = long int; _Tp = cycle; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/include/c++/10/bits/stl_heap.h:355:22:   required from 'void std::__make_heap(_RandomAccessIterator, _RandomAccessIterator, _Compare&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/include/c++/10/bits/stl_algo.h:1666:23:   required from 'void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/include/c++/10/bits/stl_algo.h:1937:25:   required from 'void std::__partial_sort(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/include/c++/10/bits/stl_algo.h:1953:27:   required from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Size = long int; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/include/c++/10/bits/stl_algo.h:1974:25:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/include/c++/10/bits/stl_algo.h:4859:18:   required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<cycle*, std::vector<cycle> >]'
books.cpp:118:47:   required from here
/usr/include/c++/10/bits/predefined_ops.h:67:22: error: no match for 'operator<' (operand types are 'cycle' and 'cycle')
   67 |       { return *__it < __val; }
      |                ~~~~~~^~~~~~~
In file included from /usr/include/c++/10/bits/stl_algobase.h:67,
                 from /usr/include/c++/10/vector:60,
                 from books.h:1,
                 from books.cpp:1:
/usr/include/c++/10/bits/stl_iterator.h:1096:5: note: candidate: 'template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)'
 1096 |     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/10/bits/stl_iterator.h:1096:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/10/bits/stl_algobase.h:71,
                 from /usr/include/c++/10/vector:60,
                 from books.h:1,
                 from books.cpp:1:
/usr/include/c++/10/bits/predefined_ops.h:67:22: note:   'cycle' is not derived from 'const __gnu_cxx::__normal_iterator<_IteratorL, _Container>'
   67 |       { return *__it < __val; }
      |                ~~~~~~^~~~~~~
In file included from /usr/include/c++/10/bits/stl_algobase.h:67,
                 from /usr/include/c++/10/vector:60,
                 from books.h:1,
                 from books.cpp:1:
/usr/include/c++/10/bits/stl_iterator.h:1104:5: note: candidate: 'template<class _Iterator, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_Iterator, _Container>&, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)'
 1104 |     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
      |     ^~~~~~~~
/usr/include/c++/10/bits/stl_iterator.h:1104:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/10/bits/stl_algobase.h:71,
                 from /usr/include/c++/10/vector:60,
                 from books.h:1,
                 from books.cpp:1:
/usr/include/c++/10/bits/predefined_ops.h:67:22: note:   'cycle' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
   67 |       { return *__it < __val; }
      |                ~~~~~~^~~~~~~