description
一棵樹上有
n 個節點,編號分別為1到
n,每個節點都有乙個權值
w 。我們將以下面的形式來要求你對這棵樹完成一些操作:
i. change ut
: 把結點
u的權值改為t
ii. qmax uv
: 詢問從點u到點
v 的路徑上的節點的最大權值
iii. qsum uv
: 詢問從點u到點
v 的路徑上的節點的權值和
注意:從點u到點
v 的路徑上的節點包括u和
v 本身
input
輸入的第一行為乙個整數
n,表示節點的個數。接下來n–
1 行,每行2個整數
a 和
b,表示節點
a 和節點
b之間有一條邊相連。接下來
n 行,每行乙個整數,第
i行的整數wi
表示節點i的權值。接下來1行,為乙個整數
q ,表示操作的總數。接下來
q行,每行乙個操作,以「change u
t」或者「qmax u
v」或者「qsum u
v」的形式給出。
對於100%的資料,保證
1<=
n<=
30000
,0<=
q<=
200000
;中途操作中保證每個節點的權值
w 在-30000到30000之間。
output
對於每個「qmax」或者「qsum」的操作,每行輸出乙個整數表示要求輸出的結果。
sample input
4 1 2
2 3
4 1
4 2 1 3
12 qmax 3 4
qmax 3 3
qmax 3 2
qmax 2 3
qsum 3 4
qsum 2 1
change 1 5
qmax 3 4
change 3 6
qmax 3 4
qmax 2 4
qsum 3 4
sample output
4 1
2 2
10 6
5 6
5 16
hint
source
思路
樹鏈剖分模板。
樹鏈剖分不會的這裡
**
#include
#include
const
int maxn=30000;
const
int inf=1000000000;
int n;
struct sigment_tree
public:int build(int now,int left,int right)
int mid=(left+right)>>1;
build(now<<1,left,mid);
build(now<<1|1,mid+1,right);
updata(now);
return
0; }
public:int modify(int now,int left,int right,int findnum,int changeval)
if(left==right)
int mid=(left+right)>>1;
modify(now<<1,left,mid,findnum,changeval);
modify(now<<1|1,mid+1,right,findnum,changeval);
updata(now);
return
0; }
public:int askmax(int now,int left,int right,int askl,int askr)
if((askl<=left)&&(askr>=right))
int mid=(left+right)>>1;
return
std::max(askmax(now<<1,left,mid,askl,askr),askmax(now<<1|1,mid+1,right,askl,askr));
}public:int asksum(int now,int left,int right,int askl,int askr)
if((askl<=left)&&(askr>=right))
int mid=(left+right)>>1;
return asksum(now<<1,left,mid,askl,askr)+asksum(now<<1|1,mid+1,right,askl,askr);
}};struct tree
public:int first_dfs(int u,int father)
//首次dfs,將deep、fa、size、wson求出來,為第二次dfs做準備
}j=pre[j];
}return
0; }
public:int second_dfs(int u,int father,int topfather)
//第二次dfs,將dfn和top求出來
int j=now[u];
while(j)
j=pre[j];
}return
0; }
public:int change(int pos,int val)
//單點修改
public:int askmax(int x,int y)
//一條路徑上求max值
res=std::max(res,st.askmax(1,1,n,dfn[top[x]],dfn[x]));
x=fa[top[x]];
}if(deep[x]>deep[y])
//top值相同,那麼x和y在同一條重鏈上
res=std::max(res,st.askmax(1,1,n,dfn[x],dfn[y]));
return res;
}public:int asksum(int x,int y)
//一條路徑上求sum值
res+=st.asksum(1,1,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}if(deep[x]>deep[y])
res+=st.asksum(1,1,n,dfn[x],dfn[y]);
return res;
}};tree t;
int m;
int main()
t.first_dfs(1,0);
t.second_dfs(1,0,1);
for(int i=1; i<=n; i++)
scanf("%d",&m);
while(m--)
if(s[1]=='s')
if(s[1]=='m')
}return
0;}
ZJOI 2008 樹的統計
一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 注意 從點...
ZJOI2008 樹的統計
zjoi2008 樹的統計 題目描述 一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到...
ZJOI2008 樹的統計
一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。我們將以下面的形式來要求你對這棵樹完成一些操作 i.change u t 把結點u的權值改為t ii.qmax u v 詢問從點u到點v的路徑上的節點的最大權值 iii.qsum u v 詢問從點u到點v的路徑上的節點的權值和 注意 從點...