看到lct的題解比較少,所以我來貢獻一篇
注意的地方and坑點
1. 只用把mmax [ 0 ](維護的最大值)初始化為極小值
2. sum [ i ] , mmax [ i ]在輸入時就可賦值為val [ i ]
3. 要先儲存下聯通的點,在輸入完val後再進行link操作
change操作
change ( x , v )表示把 val [ x ] 改成v
步驟:1. 將x點splay到根
2. 更新 val [ x ] = v
3. 進行pushup(x)操作
qmax and qsum操作
輸入x,y表示詢問x,y路徑上的最大權值或者路徑和
步驟1. 只需split ( x , y ),然後輸出 mmax [ y ] 或者 sum [ y ] 即可
2. 此時 mmax [ y ] 或 sum [ y ] 表示的就是x到y這條鏈上的最大權值 或者 權值和了
#include #include#include
#include
#include
#define mn 4000001
#define re register int
#define ll long long
#define inf 0x7fffffff
using
namespace
std;
int f[mn], val[mn], sum[mn], r[mn], son[mn][2
];int
mmax[mn], size[mn];
intfake1[mn], fake2[mn];
intzhan[mn];
intn, m, cnt;
intget(int x)
////如果連的是輕邊,他的父親的兒子裡沒有它
void pushup(int
x) void filp(int
x) void pushdown(int
x) void rotate(int
x) void splay(int
x) pushup(x);
return;}
void access(int
x) }
void makeroot(int
x) int findroot(int
x) void split(int x, int
y) void cut(int x, int
y)
return;}
void link(int x, int
y) void change(int x, int
v) int
main()
//先儲存下要link的點,等輸入完val後再操作
//巨坑
for (re i = 1; i <= n; i++)
intt;
for (re i = 1; i <= n - 1; i++) link(fake1[i], fake2[i]);
scanf("%d
", &t);
for (re i = 1; i <= t; i++)
if (s[0] == '
q' && s[1] == 'm'
)
if (s[0] == '
q' && s[1] == 's'
) }
//for(re i=1;i<=n;i++)
//printf("%d %d\n",mmax[i],sum[i]);
return0;
}
P2590 ZJOI2008 樹的統計
一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 注意 從點...
P2590 ZJOI2008 樹的統計
樹鏈剖分經典板子題,但是需要注意的是線段樹既要維護和還要維護區間最大值。第一次手搓還是很難。感覺還是不太熟練。以下是 a c includeusing namespace std const int maxn 1e5 5 define ll long long int inline ll read ...
P2590 ZJOI2008 樹的統計
一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 注意 從點...