應用範圍:將子樹的資訊合併給父親節點,並且權值線段樹的下標值域和節點數相近。
題目鏈結
題意:一棵樹有n個結點,每個結點都是一種顏色,每個顏色有乙個編號,求樹中每個子樹的最多的顏色編號的和。
\(1 <= n<=1e5\)
解法:線段樹合併,這個東西的時空複雜度都很玄學,姑且認為時間為\(o(nlogn)\),空間為(常數\(\times log_n\times n\)),常數一般為\(4-8\)。
#include #include using namespace std;
#define maxn 100100
#define ll long long
int n;
int fir[maxn], nxt[maxn * 2], vv[maxn * 2];
int tot = 0;
void add(int u, int v)
int cnt = 0;
int root[maxn], col[maxn];
int lz[maxn * 17 * 2], rz[maxn * 17 * 2], sum[maxn * 17 * 2];
ll ans[maxn * 17 * 2];
void pushup(int a)
if(sum[lz[a]] > sum[rz[a]])
if(sum[lz[a]] == sum[rz[a]])
return;
}int merge(int a, int b, int l, int r)
int mid = (l + r) >> 1;
lz[a] = merge(lz[a], lz[b], l, mid);
rz[a] = merge(rz[a], rz[b], mid + 1, r);
pushup(a);
return a;
}void update(int &a, int l, int r, int v)
if(mid >= v) update(lz[a], l, mid, v);
if(mid < v) update(rz[a], mid + 1, r, v);
pushup(a);
return;
}void dfs(int u, int fa)
update(root[u], 1, 100000, col[u]);
ans[u] = ans[root[u]];
}int main()
for(int i = 1; i < n; i++)
dfs(1, 0);
for(int i = 1; i <= n; i++) printf("%lld ", ans[i]);
return 0;
}
題目鏈結
注意\(ans\)要在\(dfs\)時計算,不然當前節點的\(root\)可能被父親節點繼承,然後就炸了。
#include #include using namespace std;
#define maxn 100100
#define ll long long
int n;
int fir[maxn], nxt[maxn * 2], vv[maxn * 2];
int tot = 0;
void add(int u, int v)
int cnt = 0;
int root[maxn], col[maxn];
int lz[maxn * 17 * 2], rz[maxn * 17 * 2], sum[maxn * 17 * 2];
ll ans[maxn * 17 * 2];
void pushup(int a)
if(sum[lz[a]] > sum[rz[a]])
if(sum[lz[a]] == sum[rz[a]])
return;
}int merge(int a, int b, int l, int r)
int mid = (l + r) >> 1;
lz[a] = merge(lz[a], lz[b], l, mid);
rz[a] = merge(rz[a], rz[b], mid + 1, r);
pushup(a);
return a;
}void update(int &a, int l, int r, int v)
if(mid >= v) update(lz[a], l, mid, v);
if(mid < v) update(rz[a], mid + 1, r, v);
pushup(a);
return;
}void dfs(int u, int fa)
update(root[u], 1, 100000, col[u]);
ans[u] = ans[root[u]];
}int main()
for(int i = 1; i < n; i++)
dfs(1, 0);
for(int i = 1; i <= n; i++) printf("%lld ", ans[i]);
return 0;
}
線段樹合併
做永無鄉的時候,以為是主席樹合併,後來感覺不對勁,唔。x和y是兩顆樹的根。這個演算法是從歸併演算法那引申的。實際運作的時候,考慮到了線段樹的本質 線段樹有效節點就是葉子節點。好像是句廢話。其實不是,這句話啟發我們並不需要合併一整棵樹,我們只需要處理好葉子節點,考慮把y樹合併到x上,那麼把y樹的葉子節...
線段樹合併
今天寫dsu on tree 的時候發現不會寫線段樹合併,於是滾來寫線段樹合併部落格 對於值域相同的兩個權值線段樹x xx和y yy 假設把y yy合併到x xx上 每個節點有兩種情況 其中至少有乙個節點沒有權值 x y x y x y 直接x x y x x y x x y x 0?y x x 0...
線段樹合併
某一天馬學長給我看了乙個lca的題目,然而確實是lca 樹上差分,但是僅僅有lca和樹上差分解決不了,然後我就去面向題解程式設計了。可是這個線段樹合併是個什麼東東。然而今天看書,突然看到了這個線段樹合併。就寫一下了。mmh。p4556 vani有約會 雨天的尾巴 題目背景 深繪里一直很討厭雨天。灼熱...