題目背景
深繪里一直很討厭雨天。
灼熱的天氣穿透了前半個夏天,後來一場大雨和隨之而來的洪水,澆滅了一切。
雖然深繪里家鄉的小村落對洪水有著頑固的抵抗力,但也倒了幾座老房子,幾棵老樹被連根拔起,以及田地裡的糧食被弄得一片狼藉。
無奈的深繪里和村民們只好等待救濟糧來維生。
不過救濟糧的發放方式很特別。
題目描述
首先村落裡的一共有n座房屋,並形成乙個樹狀結構。然後救濟糧分m次發放,每次選擇兩個房屋(x,y),然後對於x到y的路徑上(含x和y)每座房子裡發放一袋z型別的救濟糧。
然後深繪里想知道,當所有的救濟糧發放完畢後,每座房子裡存放的最多的是哪種救濟糧。
輸入格式
第一行兩個正整數n,m,含義如題目所示。
接下來n-1行,每行兩個數(a,b),表示(a,b)間有一條邊。
再接下來m行,每行三個數(x,y,z),含義如題目所示。
輸出格式
n行,第i行乙個整數,表示第i座房屋裡存放的最多的是哪種救濟糧,如果有多種救濟糧存放次數一樣,輸出編號最小的。
如果某座房屋裡沒有救濟糧,則對應一行輸出0。
輸入輸出樣例
輸入 #1
5 31 2
3 13 4
5 32 3 3
1 5 2
3 3 3
輸出 #1 23
302說明/提示
對於20%的資料,1 <= n, m <= 100
對於50%的資料,1 <= n, m <= 2000
對於100%的資料,1 <= n, m <= 100000, 1 <= a, b, x, y <= n, 1 <= z <= 100000
用樹上差分,對於(x,y)這條路徑,則在x,y處+1,在lca,fa(lca)處−1,然後再用線段樹合併即可。
code:
#include#include#include#includeusing namespace std;
const int n=200005,m=200000;
int n,m,cnt,tot;
int head[n],v[n<<1],next[n<<1];
int dep[n],ans[n],root[n],fa[n][25],lc[n<<5],rc[n<<5];
pairmax[n<<5];
void add(int x,int y)
void dfs(int x)
for(int i=head[x];i;i=next[i]) }}
int lca(int x,int y)
} if(x==y)
for(i=20;~i;--i)
} return fa[x][0];
}void insert(int &root,int l,int r,int pos,int num)
if(l==r)
int mid=(l+r)>>1;
if(pos<=mid)
else
max[root]=max(max[lc[root]],max[rc[root]]);
}int merge(int x,int y,int l,int r)
if(!y)
int mid=(l+r)>>1;
if(l==r)
lc[x]=merge(lc[x],lc[y],l,mid);
rc[x]=merge(rc[x],rc[y],mid+1,r);
max[x]=max(max[lc[x]],max[rc[x]]);
return x;
}void dfs(int x)
} ans[x]=-max[root[x]].second;
}int main()
dep[1]=1;
dfs(1);
for(int i=1;i<=m;++i)
dfs(1);
for(int i=1;i<=n;i++)
return 0;
}
洛谷P4556 雨天的尾巴
p4556 vani有約會 雨天的尾巴 模板 線段樹合併 題目大意 有一顆 n 個節點的樹,m 次操作,每次將節點 u 到 v 的路徑上的每個點放乙個物品 c 最後詢問每個節點上數量最多的物品是什麼,其中數量相同的物品取編號最小者,若無物品輸出0。n,m,c leq 10 5 思路 如題目名稱,模板...
P4556 雨天的尾巴 線段樹合併
題目背景 深繪里一直很討厭雨天。灼熱的天氣穿透了前半個夏天,後來一場大雨和隨之而來的洪水,澆滅了一切。雖然深繪里家鄉的小村落對洪水有著頑固的抵抗力,但也倒了幾座老房子,幾棵老樹被連根拔起,以及田地裡的糧食被弄得一片狼藉。無奈的深繪里和村民們只好等待救濟糧來維生。不過救濟糧的發放方式很特別。題目描述 ...
P4556 雨天的尾巴 樹上差分, 樹鏈剖分
鏈結 給出一棵n n個結點的樹,有mm 次修改操作,每次操作要求將a,b a,b之間最短路徑所有點加上型別為c c的糧食11次,到最後輸出每個點所儲存的最多的糧食型別,如果有相等數量的,則輸出型別編號最小的.n,m c 1 05n,m,c 1 05整體使用 set set 維護,會發現由於左兒子對右...