天天看點

卡常數大法好!

C++ Interesting卡常數

作為一名OIer,在Noip中卡(kǎ)常數可以說是必備技巧。在此總結一下我所知卡常數的神奇手法:

  1. IO優化
  • fread 和 fwrite ,如果還想再優化有mmap....(然而并不會用,好像也沒用。。。)
  • 讀入優化(這個非常重要!!!!!!!)
inlineintRead()
{
    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;
}      
  • 輸出優化好像用不到唉( ˇˍˇ )
  1. inline

    在聲明函數之前寫上inline修飾符(就像上面Read()一樣),可以加快一下函數調用,但隻能用于一些操作簡單的函數。涉及遞歸,大号的循環等很複雜的函數,編譯器會自動忽略inline。

  2. register

    在定義變量前寫上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

恐怖啊!!!!

  1. 循環展開
循環展開也許隻是表面,在緩存和寄存器允許的情況下一條語句内大量的展開運算會刺激 CPU 并發(前提是你的 CPU 不是某 CPU)...
  1. 取模優化(僅O2)
//設模數為 mod
inlineintinc(intintintreturn x>=mod?x-mod:x;}//代替取模+
inlineintdec(intintintreturn x<0?x+mod:x;}//代替取模-      
  1. 前置 ++
後置 ++ 需要儲存臨時變量以傳回之前的值,在 STL 中非常慢。事實上,int 的後置 ++ 在實測中也比前置 ++ 慢 0.5 倍左右(UOJ 上自定義測試)
  1. 不要開bool,所有bool改成char,int是最快的(原因不明)。
  2. if()else語句比()?():()語句要慢,逗号運算符比分号運算符要快。
  3. 資料結構用指針代替數組(個人覺得無關緊要)