P2590 ZJOI2008 樹的統計

2022-05-09 19:34:45 字數 2619 閱讀 4101

一棵樹上有n個節點,編號分別為1到n,每個節點都有乙個權值w。

我們將以下面的形式來要求你對這棵樹完成一些操作:

i. change u t : 把結點u的權值改為t

ii. qmax u v: 詢問從點u到點v的路徑上的節點的最大權值

iii. qsum u v: 詢問從點u到點v的路徑上的節點的權值和

注意:從點u到點v的路徑上的節點包括u和v本身

輸入格式:

輸入檔案的第一行為乙個整數n,表示節點的個數。

接下來n – 1行,每行2個整數a和b,表示節點a和節點b之間有一條邊相連。

接下來一行n個整數,第i個整數wi表示節點i的權值。

接下來1行,為乙個整數q,表示操作的總數。

接下來q行,每行乙個操作,以「change u t」或者「qmax u v」或者「qsum u v」的形式給出。

輸出格式:

對於每個「qmax」或者「qsum」的操作,每行輸出乙個整數表示要求輸出的結果。

輸入樣例#1:

4

1 22 3

4 14 2 1 3

12qmax 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

輸出樣例#1:

412

21065

6516

對於100%的資料,保證1<=n<=30000,0<=q<=200000;中途操作中保證每個節點的權值w在-30000到30000之間。

裸的樹鏈剖分。

注意所有的值都要取最大或者最小。

有很小的負邊權!

update:資料已加強,下面的**現在不能通過!

#include#include#include#include#include#define ls k<<1

#define rs k<<1|1

using namespace std;

const int maxn=1000001;

inline void read(int &n)

while(c>='0'&&c<='9')

flag==1?n=-x:n=x;

}int n;

int a[maxn];

int fa[maxn];// 每乙個節點的父親節點

int deep[maxn];// 每乙個節點的深度

int top[maxn];// 重鏈上的頂節點

int son[maxn];// 每乙個點的重兒子

int size[maxn];// 子節點的數量

int pos[maxn];// 劃分輕重鏈之後的編號

int tot;// 總結點的數量

struct node

tree[maxn];

struct edge

edge[maxn];

int head[maxn];

int num=1;

//int nowmax=-1;

int nowsum=0;

void update(int k)

void add_edge(int x,int y)

int dfs1(int now,int nowfa,int nowdeep) }}

void dfs2(int now,int nowid)

void build_tree(int k,int ll,int rr)

int mid=(ll+rr)>>1;

build_tree(ls,ll,mid);

build_tree(rs,mid+1,rr);

update(k);

}void insert(int k,int pos,int val)

int mid=(tree[k].l+tree[k].r)>>1;

if(pos<=mid)

insert(ls,pos,val);

if(pos>mid)

insert(rs,pos,val);

update(k); }

int querymax(int k,int ll,int rr)

int askmax(int u,int v)

int querysum(int k,int ll,int rr)

int asksum(int u,int v)

int main()

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

read(a[i]);

dfs1(1,0,0);

dfs2(1,1);

build_tree(1,1,n);

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

insert(1,pos[i],a[i]);

int q;

read(q);

for(int i=1;i<=q;i++)

else if(s[1]=='m')// 最大值

else//求和

}return 0;

}

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的路徑上的節點的權值和 注意 從點...