因為是塗色問題,可以採用標記l 處+1和r+1處-1,把樹狀結構通過樹鏈剖分轉換成線性,利用線段樹維護顏色中出現的最多的,利用二分查詢能夠找到出現次數最多且序號最小的顏色
#include #include #include #include #define max 200007
using namespace std;
int n,m,z;
struct edge
e[max<<2];
int head[max];
int cc;
void add ( int u , int v , int c = 0 )
int dep[max],siz[max],fa[max],tid[max],son[max],top[max],rank[max],tim;
void init ( )
void dfs1 ( int u = 1 , int p = 0 , int d = 0 )
}void dfs2 ( int u = 1, int tp = 1 )
}struct tree
tree[max<<2];
void build ( int u , int l , int r )
void push_up ( int u )
void update ( int u , int x , int v )
int mid = l + r >> 1;
if ( x > mid ) update ( u<<1|1 , x , v );
else update ( u<<1 , x , v );
push_up ( u );
}int query ( int u )
void find ( int x , int y , int c )
if ( dep[x] > dep[y] ) swap ( x , y );
add ( tid[x] , 1 , c );
add ( tid[y]+1 , -1 , c );
} int ans[max];
int main ( )
init ( );
dfs1 ( );
dfs2 ( );
memset ( head , -1 , sizeof ( head ) );
cc = 0;
for ( int i = 0 ; i < m ; i++ )
build ( 1 , 0 , 100001 );
for ( int u = 1 ; u <= n ; u++ )
for ( int i = 1 ; i <= n ; i++ )
printf ( "%d\n" , ans[i] );
}}
hdu5029 樹鏈剖分
這題絕對好題。題意很簡單,也很容易想到樹鏈剖分,之後就不太好做了。開始想的是按顏色排序,然後每次處理一種顏色,求出最優解。這樣做的話,最壞情況會退化到n 2,不可接受。之後用線段樹維護,乙個節點只存在一種顏色,而且排序之後能保證在樹中顏色不會交叉,pushdown的時候可以將兩種都不是當前正在處理的...
HDU 5029 樹鏈剖分 權值線段樹
題目鏈結 題意 給定一顆n個結點的樹,進行m次染色操作,對於每一次染色操作是選擇樹上的一條路徑,將路徑上所有節點都染上第z zz種顏色。輸出m次操作以後,每乙個節點上染色次數最多的顏色。1 n m,z 1 e5 1 n,m,z 1e5 1 n m,z 1 e5思路 對於樹上的路徑操作,自然能夠想到使...
樹鏈剖分 樹鏈剖分講解
好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 vector v maxn int size maxn dep maxn val maxn id maxn hson maxn top maxn fa maxn 定義 int edge 1,num 1 struct tree e ma...