SPOJ 375 QTREE 樹鏈剖分入門題

2021-08-04 08:53:26 字數 1485 閱讀 6314

題目大意:對一棵有n(n<=10000)個點的樹若干次操作,每次操作可以把第i條邊的權值改為w,或者求u節點到v節點的路徑上所有邊的最大權值。

解題思路:對這棵樹進行樹鏈剖分,然後用線段樹維護區間最大值。

樹鏈剖分理解:通過規定一種特殊的次序,將樹形結構變為線性結構,從而可以用多種資料結構來解決樹上路徑方面的問題。

ac**:

/*@author: wchhlbt

@date: 2017/7/22

*/#include #define fori(x) for(int i=0;ip;

const double pi = acos(-1.0);

int dx[4] = ;

int dy[4] = ;

int n,m;

int ans;

int cnt;

struct edge

}edge[maxn];

vectore[maxn];

/*樹鏈剖分

cnt初始化為0

son陣列初始化為-1

getans()根據實際維護的值進行修改

*/int son[maxn];//重兒子

int size[maxn];//子數大小

int fa[maxn];//父節點

int dep[maxn];//深度

void dfs1(int u, int f, int d)//維護重兒子,深度,父節點,子樹大小

}int id[maxn];

int top[maxn];

//dfs2建立重鏈

void dfs2(int u, int tp)//tp為當前重鏈的起始點

int update(int root, int pos, int val)//將pos位置的值替換為val

int query(int root, int l, int r)

int temp = query(1,id[tp1],id[u]);//考慮tp1上面的輕鏈

ans = max(ans,temp);

u = fa[tp1]; tp1 = top[u];//更新u節點為重鏈頭節點的父節點

}if(u==v) return ans;

//處理u、v在一條重鏈上的情況

if(dep[v]>dep[u]) swap(u,v),swap(tp1,tp2);

int temp = query(1,id[son[v]],id[u]);

ans = max(ans,temp);

return ans;

}void init()//全部初始化操作

{ cnt = 0;//重新編號樹上的id

memset(son,-1,sizeof(son));

for(int i = 0; i

SPOJ375 樹鏈剖分

題目 query on a tree 題意 給定一棵樹,告訴了每條邊的權值,然後給出兩種操作 1 把第i條邊的權值改為val 2 詢問a,b路徑上權值最大的邊 分析 本題與hdu3966差不多,區別就是 hdu3966是告訴樹中點權的值,這裡是邊權。所以我們可以轉化,用邊的孩子節點來表示該邊。inc...

spoj375 樹鏈剖分

第一次寫樹鏈剖分的題目,下面說下我對樹鏈剖分的理解 以spoj為例,題意是給你一棵樹,有兩種操作,一種是修改某條邊的權值,一種是詢問節點a到節點b之間的路徑上所有邊的最大路徑。處理以上所有的資訊只需要兩個dfs就可以 第乙個dfs,dfs1處理father,size,depth,son 如下 voi...

SPOJ375 樹鏈剖分

題目 query on a tree 題意 給定一棵樹,告訴了每條邊的權值,然後給出兩種操作 1 把第i條邊的權值改為val 2 詢問a,b路徑上權值最大的邊 分析 本題與hdu3966差不多,區別就是 hdu3966是告訴樹中點權的值,這裡是邊權。所以我們可以轉化,用邊的孩子節點來表示該邊。inc...