1. 程式人生 > >NOIP卡常數技巧

NOIP卡常數技巧

摘自某位大佬的部落格(http://www.cnblogs.com/widerg/p/7353866.html
1.IO優化
fread 和 fwrite ,如果還想再優化有mmap….(然而並不會用,好像也沒用。。。)
讀入優化(這個非常重要!!!!!!!)

inline int Read()
{
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();}
    return
x*f; }

當然還有另一種但是這種只適用於讀取非負數如下:

#inline int read(){
    int num;
    char ch;
    while((ch=getchar())<'0' || ch>'9');
    num=ch-'0';
    while((ch=getchar())>='0' && ch<='9'){
        num=num*10+ch-'0';
    }
    return 0;
}

輸出優化:

inline void out(int x){
    if(x>=10){
        out
(x/10); } putchar(x%10+'0'); }

大家注意一下快速讀入和快速輸出儘量爆int的資料就儘量不要用了我原來用快速輸出就WA掉了但是用printf就沒有問題
2inline
在宣告函式之前寫上inline修飾符(就像上面Read()一樣),可以加快一下函式呼叫,但只能用於一些操作簡單的函式。涉及遞迴,大號的迴圈等很複雜的函式,編譯器會自動忽略inline。
3register
在定義變數前寫上register修飾符,用於把變數放到CPU暫存器中,適用於一些使用頻繁的變數:

register int n,m;

暫存器空間有限,如果放得變數太多,多餘變數就會被放到一般記憶體中;
快,不是一般的快,快到什麼程度呢?:

register int a=0;
for(register int i=1;i<=999999999;i++)
a++;
int a=0;
for(int i=1;i<=999999999;i++)
a++;

結果:
優化:0.2826 second
不優化:1.944 second
恐怖啊!!!!
4迴圈展開
迴圈展開也許只是表面,在快取和暫存器允許的情況下一條語句內大量的展開運算會刺激 CPU 併發(前提是你的 CPU 不是某 CPU)…
5取模優化(僅O2)

//設模數為 mod
inline int inc(int x,int v,int mod){x+=v;return x>=mod?x-mod:x;}//代替取模+
inline int dec(int x,int v,int mod){x-=v;return x<0?x+mod:x;}//代替取模-

6前置 ++

後置 ++ 需要儲存臨時變數以返回之前的值,在 STL 中非常慢。事實上,int 的後置 ++ 在實測中也比前置 ++  0.5 倍左右(UOJ 上自定義測試)

7不要開bool,所有bool改成char,int是最快的(原因不明)。
8if()else語句比()?():()語句要慢,逗號運算子比分號運算子要快。
9資料結構用指標代替陣列(個人覺得無關緊要)

陣列在用方括號時做了一次加法才能取地址!
所以在那些計算量超大的資料結構中,你每次都多做了一次加法!!!在 64 位系統下是   long long 相加,效率可想而知。

感謝這位不知名的神犇