FastIO

From EOJ Wiki
Revision as of 12:32, 22 March 2018 by Kblack (talk | contribs) (Created page with "== kblack's == <syntaxhighlight lang='cpp'> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef long double ld; ld PI = acos((ld)-1.0); co...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

kblack's

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;

typedef long double ld;

ld PI = acos((ld)-1.0);

const double eps = 1e-9;

//#define ENABLE_FREAD

namespace io_impl
{
	inline bool maybe_digit(char c) {
		return c >= '0' && c <= '9';
	}

	struct io_s {
	private:
		bool negative;
		bool ok = true;
		char ch = next_char();

		int precious;
		long double epslion;

#ifdef ENABLE_FREAD
		inline char next_char() {
			static char buf[100000], *p1 = buf, *p2 = buf;
			return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
		}
#else
		inline char next_char() const {
			return getchar();
		}
#endif
	public:

#pragma region read int

		template<typename T>
		inline bool rn(T& _v) {
			negative = false;
			_v = 0;
			while (!maybe_digit(ch) && ch != EOF) {
				negative = ch == '-'; ch = next_char();
			};
			if (ch == EOF)return ok = false;
			do {
				_v = (_v << 1) + (_v << 3) + ch - '0';
			} while (maybe_digit(ch = next_char()));
			if (negative) _v = -_v;
			return true;
		}

		template<typename T>
		inline void rn_unsafe(T& _v) {
			negative = false;
			_v = 0;
			while (!maybe_digit(ch)) {
				negative = ch == '-'; ch = next_char();
			};
			do {
				_v = (_v << 1) + (_v << 3) + ch - '0';
			} while (maybe_digit(ch = next_char()));
			if (negative) _v = -_v;
		}

		template<typename T>
		inline T rn() {
			T v = T();
			rn_unsafe(v);
			return v;
		}

#pragma endregion

#pragma region read unsigned

		template<typename T>
		inline bool run(T& _v) {
			_v = 0;
			while (!maybe_digit(ch) && ch != EOF) ch = next_char();
			if (ch == EOF)return ok = false;
			do {
				_v = (_v << 1) + (_v << 3) + ch - '0';
			} while (maybe_digit(ch = next_char()));
			return true;
		}

		template<typename T>
		inline void run_unsafe(T& _v) {
			_v = 0;
			while (!maybe_digit(ch)) ch = next_char();
			do {
				_v = (_v << 1) + (_v << 3) + ch - '0';
			} while (maybe_digit(ch = next_char()));
		}

		template<typename T>
		inline T run() {
			T v = T();
			run_unsafe(v);
			return v;
		}

#pragma endregion

#pragma region read float

		template<typename T>
		inline bool rd(T& _v) {
			negative = false;
			_v = 0;
			while (!maybe_digit(ch) && ch != EOF) {
				negative = ch == '-'; ch = next_char();
			};
			if (ch == EOF)return ok = false;
			do {
				_v = (_v * 10) + (ch - '0');
			} while (maybe_digit(ch = next_char()));
			static int stk[70], tp;
			if (ch == '.')
			{
				tp = 0;
				T _v2 = 0;
				while (maybe_digit(ch = next_char())) {
					stk[tp++] = ch - '0';
				}
				while (tp--)
				{
					_v2 = _v2 / 10 + stk[tp];
				}
				_v += _v2 / 10;
			}
			if (ch == 'e' || ch == 'E')
			{
				ch = next_char();
				static bool _neg = false;
				if (ch == '+') ch = next_char();
				else if (ch == '-') _neg = true, ch = next_char();
				if(maybe_digit(ch))
				{
					_v *= pow(10, run<LL>()*(_neg ? -1 : 1));
				}
			}
			if (negative) _v = -_v;
			return true;
		}

		template<typename T>
		inline T rd() {
			T v = T();
			rd(v);
			return v;
		}

#pragma endregion

#pragma region read string

		inline int gets(char* s) {
			char* c = s;
			while (ch == '\n' || ch == '\r' || ch == ' ') ch = next_char();
			if (ch == EOF) return (ok = false), *c = 0;
			do {
				*(c++) = ch;
				ch = next_char();
			} while (ch != '\n' && ch != '\r' && ch != ' ' && ch != EOF);
			*(c++) = '\0';
			return static_cast<int>(c - s - 1);
		}

		inline int getline(char* s) {
			char* c = s;
			while (ch == '\n' || ch == '\r') ch = next_char();
			if (ch == EOF) return (ok = false), *c = 0;
			do {
				*(c++) = ch;
				ch = next_char();
			} while (ch != '\n' && ch != '\r' && ch != EOF);
			*(c++) = '\0';
			return static_cast<int>(c - s - 1);
		}

		inline char get_alpha() {
			while (!isalpha(ch)) ch = next_char();
			const char ret = ch; ch = next_char();
			return ret;
		}

		inline char get_nonblank() {
			while (iswspace(ch)) ch = next_char();
			const char ret = ch; ch = next_char();
			return ret;
		}

		inline char get_char()
		{
			const char ret = ch; ch = next_char();
			return ret;
		}

		template<typename T>
		inline void o(T p) {
			static int stk[70], tp;
			if (p == 0) { putchar('0'); return; }
			if (p < 0) { p = -p; putchar('-'); }
			while (p) stk[++tp] = p % 10, p /= 10;
			while (tp) putchar(stk[tp--] + '0');
		}

		template<typename T>
		inline void od(T v) {
			static int stk[70], tp;
			tp = 0;
			if (fabs(v)< epslion/10) {
				putchar('0');
				if(precious>0) {
					putchar('.');
					for(int i = 0; i<precious; ++i) putchar('0');
				}
				return;
			} else {
				if (v < 0) { v = -v; putchar('-'); }
				v+=epslion/2;
				T p = floor(v)+epslion/10;
				while (fabs(p)>1-epslion) {
					stk[++tp] = fmod(p, 10), p /= 10;
				}
				while (tp) putchar(stk[tp--] + '0');
			}
			if(precious==0) return;
			putchar('.');
			v-=floor(v);
			for(int i = 0; i<precious; ++i) {
				v*=10;
				putchar((int)floor(v)+'0');
				v = fmod(v, 1);
			}
		}

#pragma endregion

#pragma region enhancement

		typedef void io_operator(io_s& v);
		typedef char* charptr;

		template<typename T>
		inline io_s& operator >> (T& x)
		{
			if (numeric_limits<T>::is_signed) rn(x);
			else run(x);
			return *this;
		}

		template<typename T>
		inline io_s& operator << (const T& x);

		inline io_s& operator << (io_operator* v)
		{
			v(*this);
			return *this;
		}

		operator bool() const { return ok; }

		void set_precious(int x) {
			precious = x;
			epslion = pow(10, -x);
		}

		inline int ri() { return rn<int>(); }
		inline LL rll() { return rn<LL>(); }

		inline static void new_line(io_s& v)
		{
			putchar('\n');
		}

		inline static void flush(io_s& v)
		{
			fflush(stdout);
		}
#pragma endregion
	};

#pragma region input fix

	template<>
	inline io_s& io_s::operator >> (char*& x)
	{
		gets(x);
		return *this;
	}

	template<>
	inline io_s& io_s::operator >> (float& x)
	{
		rd(x);
		return *this;
	}

	template<>
	inline io_s& io_s::operator >> (double& x)
	{
		rd(x);
		return *this;
	}

	template<>
	inline io_s& io_s::operator >> (long double& x)
	{
		rd(x);
		return *this;
	}

#pragma region output fix

	template<>
	inline void io_s::o(const char p) {
		putchar(p);
	}

	template<>
	inline void io_s::o(const char* p) {
		printf(p);
	}

	template<>
	inline void io_s::o(float p) {
		od(p);
	}

	template<>
	inline void io_s::o(double p) {
		od(p);
	}

	template<>
	inline void io_s::o(long double p) {
		od(p);
	}

	template<typename T>
	inline io_s& io_s::operator << (const T& x)
	{
		o(x);
		return *this;
	}

	io_s::io_operator* nl = io_s::new_line;
	io_s::io_operator* fl = io_s::flush;

#pragma endregion
}

using namespace io_impl;

io_s io;