一篇部落格
最常用,也是最簡單的演算法,實質就是直接對暴力使用倍增優化將複雜度降低達到需求。有樹上的倍增和區間的倍增
\(depth\)為每個節點的深度,\(fa[i][j]\),i節點的\(2^j\)的父親。\(lg[i]=log_2+1\)
const int maxn=5000001;
int depth[maxn],fa[maxn][22],lg[maxn];
vectorg[maxn];
void dfs(int now,int fath)//dfs初始化fa和depth,傳入引數為根節點
for(int i=0;idepth[y])
if(x==y)
return x;
for(int k=lg[depth[x]]-1;k>=0;--k)//樹上倍增 }
return fa[x][0];
}main(void)
;int ans22=0;
void dfs(int now,int fath)
for(int i=0;idepth[y])
if(x==y)
for(int k=lg[depth[x]]-1;k>=0;--k)
運用lca中的dfs,求得所有點到根的異或
const int maxn=5000001;
int depth[maxn],fa[maxn][22],lg[maxn];
vectorg[maxn];
int ans1=0;
int ans2[20000]=;
int ans22=0;
void dfs(int now,int fath)
for(int i=0;idepth[y])
if(x==y)
for(int k=lg[depth[x]]-1;k>=0;--k)
要求分配軍隊,運用了lca的dfs,得到每個點的祖先節點情況。
const int n=5e4+3;
ll sum,dis[n],dist[n];
int n,m,u,cnt,cont;
int am[n],lg[n],f[n][17],dp[n],vis[n],fre[n],b[n],pl[n],nee[n];
int tt,head[n],to[n<<1],nex[n<<1],w[n<<1];
vectorarv[n];
struct lca
return ;
} int get(int x,int y)
}lca;
inline void add(int x,int y,int w)
inline bool dfs(int g,int f)
return flag;
}inline bool check(ll mid)
vis[y]=1;//將當前節點標記;
int j=pl[y];//找到對應的根節點的子節點的編號;
if(j)
if(cnt1>cnt2)return false;//如果軍隊數小於節點數,就無法完全覆蓋;
sort(nee+1,nee+1+cnt1);
sort(fre+1,fre+1+cnt2);//排序;
while(cnt1)
return l;
}int main()
while(c>='0'&&c<='9')
return x*f;
}struct st
for(int j=1;j<=21;j++)
}} int check(int l,int r) };
main(void)
}
倍增法(ST演算法)
3.典型例題 演算法思想 st演算法,適用於rmq問題 區間最大值 也就是求出乙個序列中,數值最大的一項。樸素做法自然是一遍掃瞄找最大值,但是當題目詢問次數很多的時候,就很有可能超時,因此用倍增演算法來進行乙個優化。以下是st演算法求解rmq問題的實現 首先,我們用f i j f i j f i j...
倍增小結 ST 與 LCA
倍增我是真滴不會 倍增法 英語 binary lifting 顧名思義就是翻倍。能夠使線性的處理轉化為對數級的處理,大大地優化時間複雜度。ps 上次學倍增lca,沒學會,老老實實為了嚴格次小生成樹滾回來重新學 st表 n log n 的預處理與 o 1 的查詢 感性理解一下 對於每次詢問 l,r q...
ST表(倍增表)
介紹st表之前先看看rmq問題是什麼東西吧 rmq range maximum minimum query 顧名思義,這就是指區間最大或最小值 區間最值 st表 spars table,一種可以解決rmq的,基於倍增的資料結構 令 f i j 表示從 i 開始連續 2 j 個數中的最值,如果 i 後...