題目鏈結
題意:給定一顆n個結點的樹,進行m次染色操作,對於每一次染色操作是選擇樹上的一條路徑,將路徑上所有節點都染上第z
zz種顏色。
輸出m次操作以後,每乙個節點上染色次數最多的顏色。
1
<=n
,m,z
<=1
e5
1<=n,m,z <= 1e5
1<=n
,m,z
<=1
e5思路:
對於樹上的路徑操作,自然能夠想到使用樹鏈剖分,將樹形結構轉化為線形結構,並能夠將樹上的路徑劃分為幾個連續的區間。
隨後問題轉化為:
在乙個一維數軸上,進行m次染色,每次選擇乙個區間染成某一種顏色,問最後每乙個點染色次數最多的顏色。
對於該問題,我們首先考慮乙個簡單的版本,即只存在一種顏色,我們如何求出該顏色在每乙個點的染色次數呢?
考慮掃瞄線,即對於每乙個區間[l,
r]
[l,r]
[l,r
],我們在l
ll處加1,r+1
r+1r+
1處減1
11,最後掃一遍即可。
那對於多種顏色,雖然計算還是+1或者-1的計算,但為了區分不同的顏色,對於顏色k
kk,我們標記時使用+k+k
+k或− k-k
−k。此時對於該題我們就有了清晰的思路,首先對於每乙個點開乙個vector,用於儲存該點的標記。
隨後對於每一次染色,使用樹鏈剖分將路徑轉化為幾個連續的區間,對於區間[l,
r]
[l,r]
[l,r
]染第k
kk種顏色,我們就更新:
vector<
int> vec[n+1]
;for x in all_segment:
vec[x.l]
.push_back
(x.k)
; vec[x.r]
.push_back
(-x.k)
;
定義陣列:ans[i]:第i種節點當前的染色次數
按順序遍歷節點,隨後遍歷其對應的vector,更新ans陣列。
隨後從ans陣列裡面找出值最大且序號最小的下標即可。
這一步可以使用權值線段樹進行優化。
此題得解。
**:
#include
#include
#include
#include
#include
using
namespace std;
typedef
long
long ll;
#define lson rt<<1
#define rson rt<<1|1
const
int a =
1e5+10;
class
grag[a<<2]
;class
seg_tree
tree[a<<2]
;int n,m,head[a]
,tot,twt;
int fa[a]
,dep[a]
,siz[a]
,son[a]
,top[a]
,pos[a]
,id[a]
,ans[a]
;vector<
int> v[a]
;void
init()
siz[0]
=0; tot = twt =0;
}void
add(
int u,
int v)
void
dfs(
int u,
int pre,
int d)
}void
dfs(
int u,
int tp)
}void
calc
(int x,
int y,
int c)
if(dep[x]
> dep[y]
)swap
(x,y)
; v[pos[x]].
push_back
(c);
v[pos[y]+1
].push_back
(-c);}
void
push_up
(int rt)
void
build_tree
(int rt,
int l,
int r)
void
update
(int rt,
int pos,
int c)
int mid =
(l+r)
>>1;
if(pos <= mid)
update
(lson,pos,c)
;else
update
(rson,pos,c)
;push_up
(rt);}
intquery
(int rt,
int mx)
intmain()
dfs(1,
1,1)
;dfs(1
,1);
int mx =0;
for(
int i=
1;i<=m ;i++
)build_tree(1
,1,a);
for(
int i=
1;i<=n ;i++)if
(tree[1]
.mx ==
0) ans[id[i]]=
0;else ans[id[i]]=
query(1
,tree[1]
.mx);}
for(
int i=
1;i<=n ;i++)}
return0;
}
hdu5029 樹鏈剖分
這題絕對好題。題意很簡單,也很容易想到樹鏈剖分,之後就不太好做了。開始想的是按顏色排序,然後每次處理一種顏色,求出最優解。這樣做的話,最壞情況會退化到n 2,不可接受。之後用線段樹維護,乙個節點只存在一種顏色,而且排序之後能保證在樹中顏色不會交叉,pushdown的時候可以將兩種都不是當前正在處理的...
hdu 5029 樹鏈剖分 鍊錶
因為是塗色問題,可以採用標記l 處 和r 處 1,把樹狀結構通過樹鏈剖分轉換成線性,利用線段樹維護顏色中出現的最多的,利用二分查詢能夠找到出現次數最多且序號最小的顏色 include include include include define max 200007 using namespace ...
hdu 3966(樹鏈剖分 線段樹)
題意 給出一棵樹,每個節點有一些敵人,有三種操作,i x,y,路徑上的所有點的人數 w。d x,y,路徑上的所有點的人數 w。q 節點x的人數。pragma comment linker,stack 1024000000,1024000000 include include include usin...