樹鏈剖分學習
核心:節點u的輕兒子為v 輕兒子的性質:size[v] <= size[u] / 2
故:每走一條輕鏈,節點數減少一半
又因:兩個節點之間的路徑,必為重鏈和輕邊交替
故:從根結點到樹上任意點經過的輕邊以及重鏈都不會超過logn條
樹鏈剖分模版題
題意:有一棵n個節點的樹(1<=n<=10000),n-1條邊,邊的編號為1~n-1,每條邊有乙個權值,要求模擬兩種操作:
1:query x y 求節點x和節點y之間的路徑中權值最大的邊。
2:change p k修改第p條邊的權值為k。
1 #include2 #include3 #include4 #include5 #include6using
namespace
std;78
const
int n=10010;9
char s[10
];10
struct
trnodet[2*n];
13struct
nodea[2*n],b[n];
16int
n,tl,z,len;
17int
first[n],tot[n],son[n],fa[n],dep[n],ys[n],top[n];
1819
int maxx(int x,int y)
2021
void ins(int x,int y,int
d)22
2728
int build_tree(int l,int
r)29
39return
x;40}41
42void change(int x,int p,int
c)43
45int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)>>1;46
if(p<=mid) change(lc,p,c);
47else
change(rc,p,c);
48 t[x].c=maxx(t[lc].c,t[rc].c);49}
5051
int query(int x,int l,int
r)52
5960
void dfs1(int
x)6173}
7475
void dfs2(int x,int
tp)7685}
8687
int solve(int x,int
y)88
96if(x==y) return
ans;
97else
98102
}103
104int
main()
105122 dfs1(1
);123 dfs2(1,1
);124 build_tree(1
,z);
125for(int i=1;iif(dep[b[i].x]>dep[b[i].y]) swap(b[i].x,b[i].y);
126for(int i=1;i1
,ys[b[i].y],b[i].d);
127while(1
)128
136if(s[0]=='c'
)137
141if(s[0]=='
d') break
;142
}143
}144
return0;
145 }
posted @
2016-08-07 14:21
攔路雨偏似雪花 閱讀(
...)
編輯收藏
SPOJ QTree5 樹鏈剖分
感覺之前拿點分治水過心裡過意不去,mdzz,我還是打了乙份樹鏈剖分的code,具體方法與qtree4相同 詳見 維護線段樹的合併時的值。include define mid l r 1 define pf push front using namespace std const int n 1e5 ...
SPOJ QTREE2 樹鏈剖分
題意 有一棵n個節點的樹 1 n 10000 n 1條邊,邊的編號為1 n 1,每條邊有乙個權值,要求模擬兩種操作 1 dist a b 求 點a到點b之間的距離 2 kth a b k 求從a出發到b遇到的第k個節點的編號 qtree系列的第二題。求dist就不用說啦,主要是求第k個。方法一 我是...
SPOJ QTREE2 樹鏈剖分
題意 有一棵n個節點的樹 1 n 10000 n 1條邊,邊的編號為1 n 1,每條邊有乙個權值,要求模擬兩種操作 1 dist a b 求 點a到點b之間的距離 2 kth a b k 求從a出發到b遇到的第k個節點的編號 qtree系列的第二題。求dist就不用說啦,主要是求第k個。方法一 我是...