轉載自:https://blog.csdn.net/IOT_SONG/article/details/51477071html
https://blog.csdn.net/qq_33957603/article/details/79946680算法
https://blog.csdn.net/leader_one/article/details/78430083數組
https://blog.csdn.net/xuxiayang/article/details/81021585 函數
傳說中的神級快讀fread:spa
#define getchar() (S==T&&(T=(S=BB)+fread(BB,1,1<<15,stdin),S==T)?EOF:*S++)
char BB[1<<15],*S=BB,*T=BB;;
IL LL read()
{
f=0;Re char c;
while(c=getchar(),c<=47||c>=58);f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),c>=48&&c<=57) f=(f<<3)+(f<<1)+c-48;
return f;
} .net
快輸慎用:指針
基本程序
void write(int x)
{
/*在這一行你能夠進行一些特殊處理和判斷,例如處理負數等*/
if(x>9) write(x/10);//能分解則分解
putchar(x%10+48);//利用C++putchar速度快的因素加速輸出
}
改造輸出優化,需搭配上面的進行
1.輸出後空格
void writespace(int x)
{
write(x);putchar(32);return;//這裏仍然利用了puchar速度快的優勢
}
2.輸出後換行
void writeln(int x)
{
write(x);putchar(10);//依舊利用putchar快速的優勢,達到十分快速的效果
} code
0.位運算心法:(掌握粗體字)
&(與邏輯):有0出0,全1出1;
|(或邏輯):有1出1,全0出1;
~(非邏輯):空便是色,色便是空;
^(異或):相異出1,相同出0;
1. 若是乘上一個2的倍數數值,能夠改用左移運算(Left Shift) 加速 300%
x = x * 2;
x = x * 64;
//改成:
x = x << 1; // 2 == 21
x = x << 6; // 64 == 26
2. 若是除上一個 2 的倍數數值,能夠改用右移運算加速 350%
x = x / 2;
x = x / 64;
//改成:
x = x >> 1; // 2 == 21
x = x >> 6; // 64 == 26
3. 數值轉整數加速 10%
x = int(1.232)
//改成:
x = 1.232 >> 0;
4. 交換兩個數值(swap),使用 XOR 能夠加速20%
var t:int = a;
a = b;
b = t;
//equals:
a = a^b;
b = a^b;
a = a^b;
5. 正負號轉換,能夠加入 300%
i = -i;
//改成
i = ~i + 1; // NOT 寫法
//或
i = (i ^ -1) + 1; // XOR 寫法
6. 取餘數,若是除數爲 2 的倍數,可利用 AND 運算加速 600%
x=131 % 4;
//equals:
x=131 & (4 - 1);
7. 利用 AND 運算檢查整數是否爲 2 的倍數,能夠加速 600%
isEven = (i % 2) == 0;
//equals:
isEven = (i & 1) == 0;
8. 加速 Math.abs 600% 的寫法1,寫法2 又比寫法1加速 20%
//寫法1
i = x < 0 ? -x : x;
//寫法2
i = (x ^ (x >> 31)) - (x >> 31);
//寫法3
i=x^(~(x>>31)+1)+(x>>31);
9. 比較兩數值相乘以後是否擁有相同的符號,加速 35%
eqSign = a * b > 0;
//equals:
eqSign = a ^ b > 0;xml
10.if,else語句比三目運算符語句要慢,逗號運算符比分號運算符要快。
11.結構優化
若是你要常常調用a[x],b[x],c[x]這樣的數組,把她們寫在同一個結構體裏面會變快一些,好比f[x].a, f[x].b, f[x].c
指針比下標快。
12.能少判斷少判斷 (if)
Floyd初始化
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) gra[i][j]=inf
for(int i=1;i<=b;i++) gra[i][i]=0
是比
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j) gra[i][j]=0;
else gra[i][j]=inf
} 快80%以上的,,由於要每次去比較。
13.因爲沒有開O2優化,會致使一些原本沒有區別的變得比較明顯。
多維數組把大的數放前面:
例如 int f[10000][1000][100] 而不是 f[100][1000][10000],跑起來差距0.Xs。
有時比算法的差距還大
14.循環內的問題
E.g1
for(int i = 0; i <= n; i++)
{
work1();
work2();
}
E.g2
for(int i = 0; i <= n; i++) work1();
for(int i = 0; i <= n; i++) work2();
運行效率哪個快呢?
應該大多數人都以爲是第一種快,由於它少了一遍變量枚舉-
其實這是片面的,若是work1( )和work2( )運算量都比較大的話,是第二種更快
15.對於運算量比較小的計算式,幾個運算寫在一條式子會更快(可能不是快一點)
x= a+b; x = x%mod; 是沒有 x = (a+b)%mod 速度快的在循環量大時有奇效
16.聽說主函數用signed比int更快
17.摘自remarkable
二.運算
mod定義成const
能乘不除,能加減別用魔法模法
能位運算就別用加減乘除··
x2^n改爲<<n
/2^n改爲>>n
swap(x,y)改爲x^=y^=x^=y
模數若爲2^n能夠直接&(mod-1)
也能夠先開unsigned int最後取模
兩個小於模數相加用down(x)
(x%mod+mod)%mod改爲up(x%mod)
18.自我心得:
a=b=***沒有a=***,b=***快 在一些for循環中最好別寫連等,尤爲是多個連等。