一个比较妙的头文件快读小工具模板

2018-03-30 23:52:16


  1. 具体的使用方法一般是自己配置,所有开关都在namespace 的开头。

  2. 然后在Linux下的mmap要求使用文件输入(提交前请关闭文件开关)。

  3. 如果使用了algorithm库请在max、min前加上::(如::max(a,b))。

  4. 如果有变量名需要请取消namespace的注释,并且更改using部分。

  5. 这里的write、max、min在std>=c++11支持任意参数(N>=1)的运行,write默认使用cout,Split为分隔符。

  6. 如果有需要请自行调节,可以加上inline attribute ((always_inline))优化。

  7. 注意尽量不要更改template部分,已经设计好了。

  8. 关于输出为什么需要用cout原因有4:可以自己适配类型,可以自己定义流输出,输出long long和某些类型速度比scanf快,快写的某些类型(例如double)不方便实现。

  9. 如有Bug请在评论区反馈,感谢您的反馈,作者也会不断更新。

版本线:发布-->修复一些Windows下的错误-->修复template,增强template-->(预计)增多快读支持类型-->增强快读,longlong等支持(多方法调用)-->增强文件操作,using::swap似乎有Bug,增加write输出方式-->实用改进-->修复一些Bug-->支持快速手写队列、栈-->增加小数读入支持-->修复Bug(然而在Luogu的测评环境下一直检测不到DONLINE_JUDGE也是一个比较严重的问题......)-->修复不少Bug,增加Debug工具-->修复ONLINE_JUDGE检测

//Created By Creeper_LKF
//Caution::We used "pragma" in the code
#include <cstdio>
#include <cctype>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>

#ifdef __gnu_linux__

#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

#endif

#if __cplusplus < 201103L

#include <stdarg.h>

#endif

//Algorithm Heads

#include <cmath>
#include <queue>
#include <utility>
#include <algorithm>

using namespace std;

//FILE_NAME DEFINATION

//Debug Port

#define DEBUG_PORT
#define DEBUG

#ifdef ONLINE_JUDGE
#undef DEBUG_PORT
#endif

#ifdef DEBUG_PORT
#if __cplusplus < 201103L
# pragma message "Warning : C++11 Not Use"
#ifdef DEBUG
template<typename T>
extern inline void Debug(T tar){
    cerr << tar << endl;
}
template<typename Head, typename T, typename... Tail>
extern inline void Debug(Head head, T mid, Tail... tail){
    cerr << head << ' ';
    Debug(mid, tail...);
}
#else
template<typename Head, typename T, typename... Tail>
extern inline void Debug(Head head, T mid, Tail... tail){
    return ;
}
#endif
#else
#ifdef DEBUG
template <typename T>
extern inline void Debug(T tar){
    cerr << tar << endl;
}
#else
template <typename T>
extern inline void Debug(T tar){
    return ;
}
#endif
#endif
#else
template <typename T>
extern inlnie void Debug(T tar){
    return ;
}
#endif

const char file_name[] = "b";

#define NAME_SPACE
#define USING

#ifdef NAME_SPACE
namespace LKF{
#endif
    #define SF_READ
    #define EOF_READ
    // #define ONLINE_JUDGE
    #define WRITE_ENDL
    // #define FAST_WRITE
    #define SPLIT_WRITE
    const size_t MAX_BUF_SIZE = 50000000;

    #define NEED_FILE

    #ifdef FAST_WRITE
    char outp[MAX_BUF_SIZE], *op = outp;
    #endif

    #ifdef ONLINE_JUDGE
    #undef NEED_FILE
    #endif    

    #ifdef FAST_WRITE
    #ifndef WRITE_ENDL
    #define WRITE_ENDL
    #endif
    #endif

    extern inline void FILE_OPT(){
        #ifdef NEED_FILE
        #define FILE_NAME file_name
        char IN_FILE[sizeof(FILE_NAME) + 5], OUT_FILE[sizeof(FILE_NAME) + 5];
        strcpy(IN_FILE, FILE_NAME), strcpy(OUT_FILE, FILE_NAME);
        strcat(IN_FILE, ".in"), strcat(OUT_FILE, ".out");
        freopen(IN_FILE, "r", stdin);
        freopen(OUT_FILE, "w", stdout);  
        #endif      
    }

    #ifdef __gnu_linux__

    char *pc;

    extern inline void Main_Init(){
        static bool INITED = false;
        if(INITED){
            #ifdef FAST_WRITE
            fwrite(outp, 1, op - outp - 1, stdout);
            #endif
            fclose(stdin), fclose(stdout);
        } else {
            FILE_OPT();
            pc = (char *) mmap(NULL, lseek(0, 0, SEEK_END), PROT_READ, MAP_PRIVATE, 0, 0);
            INITED = true;
        }
    }

    #else

    char buf[MAX_BUF_SIZE], *pc = buf;

    extern inline void Main_Init(){
        static bool INITED = false;
        if(INITED){
            #ifdef FAST_WRITE
            fwrite(outp, 1, op - outp - 1, stdout);
            #endif
            fclose(stdin), fclose(stdout);
        } else {
            FILE_OPT();
            fread(buf, 1, MAX_BUF_SIZE, stdin); 
            INITED = true;           
        }
    }

    #endif

    inline char read_ch(){
        char c;
        while(isspace(c = *pc ++));
        return c;
    }

    #ifdef EOF_READ

    #ifdef SF_READ

    template<typename T>
    static inline void read(T &num){
        num = 0;
        char c, sf = 1;
        while(isspace(c = *pc++));
        if(c == 45) sf = -1, c = *pc ++;
        while(num = num * 10 + c - 48, isdigit(c = *pc++));
        num *= sf;
    }

    static inline int read(){
        int num = 0;
        char c, sf = 1;
        while(isspace(c = *pc++));
        if(c == 45) sf = -1, c = *pc ++;
        while(num = num * 10 + c - 48, isdigit(c = *pc++));
        return num * sf;
    }

    static inline double read_dec(){
        double num = 0, decs = 1;
        char c, sf = 1;
        while(isspace(c = *pc ++));
        if(c == '-') sf = -1, c = *pc ++;
        while(num = num * 10 + c - 48, isdigit(c = *pc ++));
        if(c != '.') return num * sf;
        c = *pc ++;
        while(num += (decs *= 0.1) * (c - 48), isdigit(c = *pc ++));
        return num * sf;
    }

    #else

    template<typename T>
    static inline T read(T &num){
        num = 0;
        char c;
        while (isspace(c = *pc++));
        while (num = num * 10 + c - 48, isdigit(c = *pc++));
        return num;
    }

    static inline int read(){
        int num = 0;
        char c;
        while (isspace(c = *pc++));
        while (num = num * 10 + c - 48, isdigit(c = *pc++));
        return num;
    }

    static inline double read_dec(){
        double num = 0, decs = 1;
        char c;
        while(isspace(c = *pc ++));
        while(num = num * 10 + c - 48, isdigit(c = *pc ++));
        if(c != '.') return num;
        c = *pc ++;
        while(num += (c - 48) * (decs *= 0.1), isdigit(c = *pc ++));
        return num;
    }

    #endif

    #else

    #ifdef SF_READ

    template<typename T>
    static inline void read(T &num){
        num = 0;
        char c, sf = 1;
        while((c = *pc++) < 45);
        if(c == 45) sf = -1, c = *pc ++;
        while(num = num * 10 + c - 48, (c = *pc++) >= 48);
        num *= sf;
    }

    static inline int read(){
        int num = 0;
        char c, sf = 1;
        while((c = *pc++) < 45);
        if(c == 45) sf = -1, c = *pc ++;
        while(num = num * 10 + c - 48, (c = *pc++) >= 48);
        return num * sf;
    }

    static inline double read_dec(){
        double num = 0, decs = 1;
        char c, sf = 1;
        while(isspace(c = *pc ++));
        if(c == '-') sf = -1, c = *pc ++;
        while(num = num * 10 + c - 48, isdigit(c = *pc ++));
        if(c != '.') return num * sf;
        c = *pc ++;
        while(num += (decs *= 0.1) * (c - 48), isdigit(c = *pc ++));
        return num * sf;
    }

    #else

    template<typename T>
    static inline T read(T &num){
        num = 0;
        char c;
        while ((c = *pc++) < 48);
        while (num = num * 10 + c - 48, (c = *pc++) >= 48);
        return num;
    }

    static inline int read(){
        int num = 0;
        char c;
        while ((c = *pc++) < 48);
        while (num = num * 10 + c - 48, (c = *pc++) >= 48);
        return num;
    }

    static inline double read_dec(){
        double num = 0, decs = 1;
        char c;
        while(isspace(c = *pc ++));
        while(num = num * 10 + c - 48, isdigit(c = *pc ++));
        if(c != '.') return num;
        c = *pc ++;
        while(num += (c - 48) * (decs *= 0.1), isdigit(c = *pc ++));
        return num;
    }

    #endif

    #endif

    #ifdef FAST_WRITE
    template <typename T>
    inline void Call_Write(char Split, T tar){
        char buf[20];
        int top = 0;
        if(tar == 0) *op ++ = 48;
        else {
            if(tar < 0) *op ++ = '-', tar = -tar;
            while(tar) buf[++top] = tar % 10, tar /= 10;
            while(top) *op ++ = buf[top --] ^ 48;
        }
        *op ++ = Split;
    }
    template <typename T>
    inline void Call_Write(T tar){
        char buf[20];
        int top = 0;
        if(tar == 0) *op ++ = 48;
        else {
            if(tar < 0) *op ++ = '-', tar = -tar;
            while(tar) buf[++top] = tar % 10, tar /= 10;
            while(top) *op ++ = buf[top --] ^ 48;
        }
    }
    #endif

    #ifdef FAST_WRITE

    extern inline void write(){
        *op ++ = '\n';
    }

    template<typename T>
    extern inline void write(T tar){
        Call_Write(tar);
        #ifdef WRITE_ENDL
        write();
        #endif
    }

    #if __cplusplus >= 201103L

    # pragma GCC diagnostic push
    # pragma GCC diagnostic ignored "-Wunused-parameter"

    template<typename T>
    extern inline void write(char Split, T tar){
        Call_Write(tar);
        #ifdef WRITE_ENDL
        write();
        #endif
    }

    # pragma GCC diagnostic pop
    # pragma message "Warning : pragma used"

    template<typename Head, typename T, typename... Tail>
    extern inline void write(char Split, Head head, T mid, Tail... tail){
        Call_Write(Split, head);
        write(Split, mid, tail...);
    }

    #else

    template <typename T>
    extern inline void write(char Split, T tar){
        Call_Write(tar);
        #ifdef WRITE_ENDL
        write();
        #endif
    }

    #endif

    #else

    extern inline void write(){
        cout << endl;
    }

    template<typename T>
    extern inline void write(T tar){
        cout << tar;
        #ifdef WRITE_ENDL
        write();
        #endif
    }

    #if __cplusplus >= 201103L

    template<typename T>
    extern inline void write(char Split, T tar){
        cout << tar << Split;
    }

    template<typename Head, typename T, typename... Tail>
    extern inline void write(char Split, Head head, T mid, Tail... tail){
        #ifdef SPLIT_WRITE
        cout << head << Split;
        #else
        cout << head;
        #endif
        write(Split, mid, tail...);
    }

    #else

    template <typename T>
    extern inline void write(char Split, T tar){
        cout << tar << Split;
        #ifdef WRITE_ENDL
        write();
        #endif
    }

    #endif

    #endif

    template <typename T>
    extern inline void upmax(T &x, const T &y){
        if(x < y) x = y;
    }
    template <typename T>
    extern inline void upmin(T &x, const T &y){
        if(x > y) x = y;
    }

    #if __cplusplus >= 201103L

    template<typename T>
    extern inline T max(T tar){
        return tar;
    }

    template<typename T>
    extern inline T min(T tar){
        return tar;
    }

    template <typename Head, typename T, typename... Tail>
    extern inline Head max(Head head, T mid, Tail... tail){
        Head tmp = max(mid, tail...);
        return head > tmp ? head : tmp;
    }
    template <typename Head, typename T, typename... Tail>
    extern inline Head min(Head head, T mid, Tail... tail){
        Head tmp = min(mid, tail...);
        return head < tmp ? head : tmp;
    }

    #else

    template <typename T>
    extern inline T max(T a, T b){
        return a > b ? a : b;
    }
    template <typename T>
    extern inline T min(T a, T b){
        return a < b ? a : b;
    }    

    #endif

    template <typename T>
    extern inline T abs(T tar){
        return tar < 0 ? -tar : tar;
    }
    template <typename T>
    extern inline void swap(T &a, T &b){
        T t = a;
        a = b;
        b = t;
    }
#ifdef NAME_SPACE
}
#endif

//Algorithm

#ifdef NAME_SPACE
namespace LKF{
#endif

    template <typename T>
    struct Queue{
        size_t s, t;
        T *q;
        Queue(){
            s = 1, t = 0;
            q = NULL;
        }
        Queue(size_t siz){
            s = 1, t = 0;
            q = (T*)malloc(sizeof(T) * siz);
            assert(q != NULL);
        }
        inline void Re_Init(size_t siz){
            q = (T*)realloc(q, sizeof(T) * siz);
            assert(q != NULL);
        }
        ~Queue(){
            delete[] q;
        }
        inline void clear(){
            s = 1, t = 0;
        }
        inline bool empty(){
            return s > t;
        }
        inline size_t size(){
            return t - s + 1;
        }
        inline void push(T tar){
            q[++ t] = tar;
        }
        inline void pop_front(){
            s ++;
        }
        inline void pop_back(){
            t --;
        }
        inline T front(){
            return q[s];
        }
        inline T back(){
            return q[t];
        }
    };

    template <typename T>
    struct Stack{
        size_t t;
        T *s;
        Stack(){
            t = 0;
            s = NULL;
        }
        Stack(size_t siz){
            t = 0;
            s = (T*)malloc(sizeof(T) * siz);
            assert(s != NULL);
        }
        inline void Re_Init(size_t siz){
            s = (T*)realloc(s, sizeof(T) * siz);
            assert(s != NULL);
        }
        ~Stack(){
            delete[] s;
        }
        inline void clear(){
            t = 0;
        }
        inline bool empty(){
            return t == 0;
        }
        inline size_t size(){
            return t;
        }
        inline void push(T tar){
            s[++ t] = tar;
        }
        inline T top(){
            return s[t];
        }
        inline void pop(){
            t --;
        }
    };

#ifdef NAME_SPACE
}
#endif

#ifdef USING

#ifdef NAME_SPACE
using LKF::pc;
using LKF::read_ch;
using LKF::read_dec;
using LKF::read;
using LKF::Main_Init;
using LKF::write;
using LKF::upmax;
using LKF::upmin;
using LKF::max;
using LKF::min;
using LKF::abs;
// using LKF::swap;
#else
using ::pc;
using ::read_ch;
using ::read_dec;
using ::read;
using ::Main_Init;
using ::write;
using ::upmax;
using ::upmin;
using ::max;
using ::min;
using ::abs;
// using ::swap;
#endif

#endif

//Source Code