暑假培訓1 知識 7 15

2022-02-19 18:44:50 字數 4244 閱讀 9264

資料結構

下面是不常見的:

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~0

if(p[a][i]!=p[b][i]) a=p[a][i];b=p[b][i];

lca一般用於解決一類可差分的問題,比如求ab之間的最短路徑:求出a到根的路徑,b到根的路徑,減去兩倍根到lca的路徑;

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(int

x)void modify(int x,int

y)int query(int

x)int query(int l,int

r)

7.線段樹(抽象線段二叉樹;):

線段樹小記

支援區間修改,區間查詢;

主要應用:一類區間修改區間查詢的問題;

sum線段樹:

先是單點修改:

確認點的位置

更新樹的權值

區間查詢:

任何一條線段,都可以被logn條線段覆蓋;

遞迴看關係;

從最大的開始看,然後有關係就繼續往下遞迴直到被完全覆蓋,返回,統計進答案;

線段樹的節點個數2n級別的,*4防止溢位寫炸;

前置:

struct

nodet[n

<<2

];void pushup(int

rt)

建樹:

void build(int rt,int l,int

r)

int mid=(l+r)>>1

; build(rt

<<1

,l,mid);

build(rt

<<1|1,mid+1

,r);

pushup(rt);

}

單點修改a[p]=c;

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 解壓字...