#include<iostream>
#include<vector>
template <class T>
struct Triple
{
	T _value;
	size_t _row;
	size_t _col;
	Triple(const T& t =T(),size_t row = 0 ,size_t col = 0)
		:_value(t)
		, _row(row)
		, _col(col)
	{}
	

};
template <class T>
class SpareMatrix
{
public:
	SpareMatrix(T* a,size_t col,size_t row,const T invalid )
		:_row(row)
		, _col(col)
		, _invalid(invalid)
	{
		for (size_t i = 0; i < row; ++i)
		{
			for (size_t j = 0; j < col; ++j)
			{
				if (invalid != a[i*col + j])
					_array.push_back(Triple<T>(a[i*col + j], i, j));
			}
		}
	}
	SpareMatrix()
		:_row(0)
		, _col(0)
		, _invalid(0)
	{}
	SpareMatrix<T> Transport()
	{
		SpareMatrix<T> ret;

		for (size_t i = 0; i < _col; ++i)
		{
			size_t Index = 0;
			while (Index != _array.size())
			{
				if (_array[Index]._col == i)
				{
					Triple<T> temp(_array[Index]._value, _array[Index]._col, _array[Index]._row);
					ret._array.push_back(temp);
				}
				Index++;
			}
		}
		ret._col = _row;
		ret._row = _col;
		return ret;
	}
	SpareMatrix<T> QuickTransport()
	{
		int *RowCounts = new int [_col];
		int *RowStarts = new int [_col];
		memset(RowCounts, 0, sizeof(int)*_col);
		memset(RowStarts, 0, sizeof(int)*_col);
		SpareMatrix<T>ret;
		ret._array.resize(_array.size());
		size_t index = 0;
		while (index < _array.size())
		{
			RowCounts[_array[index++]._col]++;
		}
		index = 1;
		RowStarts[0] = 0;
		while (index < _col)
		{
			RowStarts[index] = RowCounts[index - 1] + RowStarts[index++ - 1];
		}
		index = 0;
		while (index < _array.size())
		{
			int &RowStart = RowStarts[_array[index]._col];
			Triple<T>tmp(_array[index]._value, _array[index]._col, _array[index]._row);
			ret._array[RowStart++] = tmp;
			index++;
		}
		ret._col = _row;
		ret._row = _col;
		ret._invalid = _invalid;
		return ret;
	}
	void Print()
	{
		size_t index = 0;
		for (size_t i = 0; i < _row; ++i)
		{
			for (size_t j = 0; j < _col; ++j)
			{
				if (index < _array.size() && _array[index]._col == j)
				{
					cout << _array[index++]._value << " ";
				}
				else
					cout << _invalid << " ";
			}
			cout << endl;
		}
		cout << endl;
	}
protected:
	size_t _row;
	size_t _col;
	T _invalid;
	std::vector<Triple<T>> _array;
};