資料結構
下面是不常見的:
1.堆堆的話是之前就學過的東西,也寫過部落格,可以帶過:
【堆】好多好多基礎知識
【堆】【洛谷例題】p1090 p1334 p1177
stl queu中有priority_queue,預設是乙個大根堆,關於如何修改priority_queu的排序順序,可以參見:【細小碎的oi小知識點總結貼】不定時更新(顯然也沒人看qwq)
2.lca:
基本用途:求樹上最短路
求lca的樸素演算法:
首先處理深度;
然後:如果deep(a)把a向上抬公升,到b的深度;
a和b同時上調,直到a=b;
複雜度o(deep(tree))
對於隨機構造的樹,可能這種演算法還可以;但是當資料別出心裁構造的伐,如果退化成一條鏈,顯然就涼涼了~;
所以我們考慮優化:
既然乙個個跳不行,我們可不可以一次跳多個?
顯然可以!
但是如果單純的列舉一次跳多少個的伐,當資料夠大時,我們列舉的範圍可能是上百萬的,也不夠優;
想到,任何乙個數都可以表示為二進位制,也就表示每個數都可以拆成若干個2的乘方相加;
令p[x][i]表示x的2^i的祖先是誰,那麼我們可以知道p[x][0]表示x的父親,通過此可以想到遞推方程: p[x][i]=p[p[x][i-1]][i-1];x的2^i祖先,等於x的2^(i-1)的祖先的2^(i-1)的祖先:
基本流程與上面相同,但是我們不再是乙個乙個的往上跳。從乘方最大的的開始列舉,如果跳上去以後父親不同就往上跳,父親相同不跳:
a和b的祖先開始是不一樣的,從lca開始,以上都一樣,但是我們無法確定lca,但是我們可以確定最後乙個不一樣的;
偽**:
for i=16~0lca一般用於解決一類可差分的問題,比如求ab之間的最短路徑:求出a到根的路徑,b到根的路徑,減去兩倍根到lca的路徑;if(p[a][i]!=p[b][i]) a=p[a][i];b=p[b][i];
3.st表:
用於求解沒有修改的區間最大值問題
mx[i][j]表示從i~i+2j-1的最大值
求乙個區間[l,r]的最大值,可以拆分為兩部分:
首先乙個區間[l,r],求出區間長度:k=l-r;
然後我們記錄p=log2k;
求這個區間的最大值,即為:max(mx[l][p],mx[r-2p+1][p]);
關於mx陣列的求法:遞推:mx[i][j]=max(mx[i][j-1],mx[i+2j-1][j-1]);
舉個栗子:
[19,46]
k=46-19=28;p=16;ans=max(mx[19][4],mx[31][4])//可能寫炸了將就著;
4.hash:
hash(字串)=>int
hash將乙個字串轉換為乙個int;
hash是允許衝突的,但是我們要盡量避免衝突;
設計hash:
1.隨便取乙個p,把字串當做p進製數(建議取質數,並且是大於字串大小的質數)
2.取字元的ascii碼*p^i(i表示此字元在此字串中是第幾位[from right to left]),然後計算一段字串的每個字元,把值相加,就是這一段字串的hash值;
3.顯然你看這個數會很大,可能會炸。我們可以取乙個大質數mod用來取模,當然也可以用unsigned long long強勢自然溢位;
具體的處理:
求字串,每個字首的雜湊值;
hi:1~i的hash值;
hi=hi-1*p+si
hash(i,j)=hj-hi*pj-i+1
5.並查集:
令fa[x]表示x的父親;樹根的父親等於本身;
查詢a和b在不在乙個集合中:找到a和b的根,比較是否相同;
如何將兩個集合合併:
找a代表元aa,b代表元bb,令fa[aa]=bb;
路徑壓縮:直接指向代表元
6.樹狀陣列:
**樹狀陣列
支援單點修改,區間查詢;其實也可以區間修改,單點查詢(利用差分)
所求所有問題,必須存在逆元?
主要應用:
1. 線段樹常數過大時
2. 線段樹功能過多時
可以在logn的時間內改變乙個數,logn的時間求字首和:
然後只講**實現,具體原理↑:
短短幾行**:
int lowbit(int7.線段樹(抽象線段二叉樹;):x)void modify(int x,int
y)int query(int
x)int query(int l,int
r)
線段樹小記
支援區間修改,區間查詢;
主要應用:一類區間修改區間查詢的問題;
sum線段樹:
先是單點修改:
確認點的位置
更新樹的權值
區間查詢:
任何一條線段,都可以被logn條線段覆蓋;
遞迴看關係;
從最大的開始看,然後有關係就繼續往下遞迴直到被完全覆蓋,返回,統計進答案;
線段樹的節點個數2n級別的,*4防止溢位寫炸;
前置:
struct建樹:nodet[n
<<2
];void pushup(int
rt)
void build(int rt,int l,int單點修改a[p]=c;r)
int mid=(l+r)>>1
; build(rt
<<1
,l,mid);
build(rt
<<1|1,mid+1
,r);
pushup(rt);
}
void modify(int rt,int p,int區間查詢:c) pushdown(rt);
int mid=(t[rt].l+t[rt].r)>>1
;
if(p<=mid) modify(rt<<1
,p,c);
else modify(rt<<1|1
,p,c);
pushup(rt);
}
int query(int rt,int l,int區間修改:r) pushdown(rt);
int ret=0
;
int mid=(t[rt].l+t[rt].r)>>1
;
if(l<=mid) ret+=query(rt<<1
,l,r);
if(mid1|1
,l,r);
return
ret;
}
懶標記:
標記這一整段線段的每乙個值,都加乙個特定的數;
懶惰的:先放在**,在沒有必要下方時,就不下放:標記下放:pushdown;
pushdown:
將此點的標記下放給左右兒子,然後自己的標記清0;
然後同時維護左右節點的區間和;
碰到這個節點就下放
void add(int rt,int l,int r,int總結啦:c) pushdown(rt);
int mid=(t[rt].l+t[rt].r)>>1
;
if(l<=mid) add(rt<<1
,l,r,c);
if(mid1|1
,l,r,c);
pushup(rt);
}
ACM暑假培訓
include include include include include 01揹包 最簡單的模板 const int max 100000 using namespace std typedef long long ll int h 1000 int main cout 例題 洛谷p1048 ...
管理知識的培訓(1)
我總結的管理知識 一 傳承 利益環 管理者是企業利益的代表著,員工利益的傾訴者 員工顧客利益的代表著 企業必須考慮員工的利益。溝通成本 用5w1h的思維方式來說,是搞不清初對方問的是什麼?在素質方面而言,是在潛意識不能承擔責任。要把這些講給自己的員工,是傳承,也是執行力的表現。二 不是沒有方法而是不...
紀中2019暑假培訓(7 5)
啊!竟然又跟之前的 學姐 住到了乙個宿舍。今天難得的起的挺早,買了乙個麵包,就去機房了。t1 交換 有兩個只含有 r g b 的字串,字元數都不超過50,且任意兩個相鄰的字元都不相同。我們可以在每個字串中各選乙個字元,進行交換。問有多少種交換方式,使兩個字串內都各有3個連續且相同的字元。t2 解壓字...