HDU 5044 Tree 樹鏈剖分

2021-06-27 07:30:59 字數 2366 閱讀 4403

題意:給一棵樹,兩種操作: add1: 給u-v路徑上所有點加上值k, add2:給u-v路徑上所有邊加上k,初始值都為0,問最後每個點和每條邊的值,輸出。

解法:樹鏈剖分可做,剖出來如果直接用線段樹來區間更新的話會tle,所以要換一種姿勢,有一種樹鏈剖分的經典姿勢就是看做樹狀陣列一樣,每次加值的時候,比如u->v之間加乙個值k,那麼在u處+k,v+1處-k即可,然後掃一遍,每次把當前位置要做的操作做完,此時總共加的值就是當前處的值,掃一遍的時候維護的是字首的和,也就是兩個ans不清零。

這題卡時間太緊,不加讀入掛會t,不加輸出掛的話跑4921ms,也是飄過,加了輸入輸出掛才稍微好點,4687ms,可能是樹鏈剖分不夠優越

**:

#pragma comment(linker, "/stack:102400000,102400000")#include 

#include

#include

#include

#include

#include

#define lll __int64

using

namespace

std;

#define n 100007

int siz[n]; //

子樹大小

int son[n]; //

重兒子int dep[n]; //

深度int pos[n],apos[n]; //

int top[n]; //

所在重鏈的祖先

int fa[n]; //

父節點lll eans[n],nans[n]; //

答案int head[2*n],tot,pos,n,m;

struct

edge

g[2*n],qe[10*n],qn[10*n];

int heade[10*n],headn[10*n],tote,totn;

struct

node

edge[n];

void

init()

void addedge(int u,int

v)void addnedge(int u,int v) //

代替vector來存操作

void addeedge(int u,int v) //

代替vector來存操作

void dfs(int u,intf)}

void dfs2(int u,int

top)

}void addedge(int u,int v,int

k) addeedge(pos[fx],k);

addeedge(pos[u]+1,-k);

u =fa[fx];

fx =top[u];

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

addeedge(pos[son[u]],k);

addeedge(pos[v]+1,-k);

}void addnode(int u,int v,int

k) addnedge(pos[fx],k);

addnedge(pos[u]+1,-k);

u =fa[fx];

fx =top[u];

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

addnedge(pos[u],k);

addnedge(pos[v]+1,-k);

}inline

intin

()

returna;}

inline

void

out(lll num)

int ans[22],top=0

;

while(num!=0

)

if(top==0

) putchar('0

');for(int i=top-1;i>=0;i--)

}int

main()

dep[

0] = 0

; dfs(

1,0);

dfs2(

1,1);

while(m--)

printf(

"case #%d:\n

",cs++);

lll ansedge = 0,ansnode = 0

;

for(i=1;i<=n;i++)

for(i=1;i<=n;i++)

for(i=1;i)

if(n == 1) puts(""); //

pe..

}

return0;

}

view code

HDU 5044 Tree (樹鏈剖分)

這題用線段樹貌似過不了,和nyoj 的士兵殺敵五一樣,經過樹鏈剖分後,就把樹剖分成許多鏈,這樣可以對整個鏈操作,結合字首和的思想,如果某個節點到祖先節點更新這間的所有節點,可以把祖先節點 k 讓當前節點編號 1 減 k 這樣最後跑一邊陣列就可以了,葉子節點的時候類似。pragma comment l...

HDU5044 Tree 樹鏈剖分

大致題意 add1 u v u到v路徑上所有點的權值加上k,add2 u 到v路徑上所有邊的權值加上k 最後輸出所有點的權值,邊的權值。樹鏈剖分預處理然後來個線性o n 的操作。剛開始用線段樹tle了.1 pragma comment linker,stack 1024000000,10240000...

poj3237 Tree 樹鏈剖分

這個題是spoj的改版 是在原來的題意上增加了區間取反操作 所以只需要在spoj375的基礎上再線段樹上增加乙個取反標誌 同時在維護乙個區間最小值 因為在區間取反了以後 區間的最大值就是區間原來的最小值 嗯 就這樣就可以了 include include include using namespac...