一些好的部落格/技巧
學習部落格
1.斜率最佳化 包含斜率最佳化的兩種做法,一些例題。
2.static關鍵字用法詳解
3.FFT
技巧
1.對於大量字串輸入的辦法:stringstream 講解
2.當一道題的數量超過 __int128
,又不想寫高精時,就可以用到 long double
,它的範圍在:\(1.2 \times 10^-4932 ~ 1.2 \times 10^4932\),雖然會掉精度,但對於:\(10 ^ {1000}\) 的資料還是綽綽有餘。輸出時要注意處理,因為如果直接輸出 double
型別,就會出現:
//型別一:整數位很多
double x=12345678;
//型別二:小數位很多,有效小數位少
double y=0.00001234;
cout<<x<<endl;
cout<<y<<endl;
輸出:
1.23457e+07
1.234e-05
我們要不讓他輸出科學計數法,可以加上 fixed
語句,然後要讓它不保留小數部分,加上 setprecision(0)
。
詳見:詳解C++中fixed,setprecision(),setw()的用法
例題:P2687 [USACO4.3] 逢低吸納Buy Low, Buy Lower
4.有關矩陣運算題的處理
- 把矩陣都封裝在結構體中
struct matrix{
int a[5][5];
void init()
{
}
void .......
{
}
.......
};
- 初始化都是單位矩陣 \(I\)。
可以封裝在結構體中。
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=(i==j);
如可以手寫出來可以用 const
直接定義,會快一點。
const matrix I
{{
{1,0,0,0,0},
{0,1,0,0,0},
{0,0,1,0,0},
{0,0,0,1,0},
{0,0,0,0,1}
}};
- 矩陣乘法可以用自定義符號方便的求出,這也封裝在結構體裡。
matrix operator*(const matrix y)const
{
matrix c;
c.init();
for(int i=0;i<=4;i++)
for(int j=0;j<=4;j++)
for(int k=0;k<=4;k++)
c.a[i][j]=(c.a[i][j]+1ll*a[i][k]*y.a[k][j]%mod)%mod;
return c;
}
也可以在外面過載運算子:
matrix operator*(const matrix &a,const matrix &b)const
{
matrix c;
c.init();
for(int i=0;i<=4;i++)
for(int j=0;j<=4;j++)
for(int k=0;k<=4;k++)
c.x[i][j]=(c.x[i][j]+1ll*a.x[i][k]*b.x[k][j]%mod)%mod;
return c;
}
- 關於樹的直徑的求法
先隨便找一個點求每個結點的深度,然後把最深的那個結點作為根,再變數一遍,樹的深度為直徑。
求直徑的路徑:只用記錄每個點的父親,然後找到最深的那個結點一直向上找即可(就是一個單向連結串列)。
void dfs(int *dd ,int u,int fa)
{
from[u]=fa;
dd[u]=dd[fa]+1;
for(int v : g[u])
{
if(v==fa) continue;
dfs(dd,v,u);
}
}
int main()
{
dfs(d,1,0);
for(int i=1;i<=n;i++) if(d[st]<d[i]) st=i;
dfs(d,st,0);
for(int i=1;i<=n;i++) if(d[ans]<d[i]) ans=i;
int len=d[ans];
while(len--) cout<<ans,ans=from[ans];
}
易錯點
-
多測不清空,oi 一場空,但清空陣列時注意範圍,是清空 \(1\) 到 \(n\),還是 \(0\) 到 \(m\)。
-
有些題看似不用卡
long long
,但在某些很小的地方要開。如特判時的語句時:
if(n*m>s) return ;
但 \(n*m\) 爆了,要開 long long
。
if((long long)n*m>(long long)s) return ;
- 莫隊中四個 while 迴圈的順序
保證正確的原則是 l<=r
(注意\(l,r\)的大小順序)。
最好記的是先擴大,也就是 --l
, ++r
,然後再縮小l++
,r--
。
while (l > a[i].l) add(c[--l]);
while (r < a[i].r) add(c[++r]);
while (l < a[i].l) del(c[l++]);
while (r > a[i].r) del(c[r--]);
還有其他的一種
oi wiki 。
排序方式
一定要看清楚判斷的先後級,是比較塊的大小還是本身端點的大小,每個莫隊的比較方式不一樣。
還有要看清楚結構體的編號。
錯誤示範(來源)
P1903 [國家集訓隊] 數顏色 / 維護佇列)
bool cmp(node2 a,node2 b)
{
if(be[a.l]!=be[b.l])return be[a.l]<be[b.l];
if(be[a.r]!=be[a.r])return be[a.r]<be[a.r];
//改成 if(be[a.r]!=be[b.r])return be[a.r]<be[b.r];
return a.t<b.t;
}