P2590 ZJOI2008 樹的統計 樹鏈剖分

2022-05-01 14:03:08 字數 3063 閱讀 2998

一棵樹上有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樹剖模板題

#includeusing

namespace

std;

//input by bxd

#define rep(i,a,b) for(int i=(a);i<=(b);i++)

#define repp(i,a,b) for(int i=(a);i>=(b);--i)

#define ri(n) scanf("%d",&(n))

#define rii(n,m) scanf("%d%d",&n,&m)

#define riii(n,m,k) scanf("%d%d%d",&n,&m,&k)

#define rs(s) scanf("%s",s);

#define ll long long

#define see(x) (cerr<

#define inf 0x3f3f3f3f

#define clr(a,v) memset(a,v,sizeof a)

#define lson l,m,pos<<1

#define rson m+1,r,pos<<1|1typedef pair

pii;

/////////////////////////////////

/const

int n=2e6+10

;const

int m=1e6;

int t[n<<2],col[n<<2],w[n],n,mod,m,root,node[n],t2[n<<2

];void up(int

pos)

void build(int l,int r,int

pos)

//w為重新編號的權值

int m=(l+r)>>1

; build(lson);build(rson);

up(pos);

}void update(int l,int r,int x,int l,int r,int

pos)

//down(r-l+1,pos);

int m=(l+r)>>1

;

if(l<=m)update(l,r,x,lson);

if(r>m)update(l,r,x,rson);

up(pos);

}int query(int l,int r,int l,int r,int

pos)

int querymax(int l,int r,int l,int r ,int

pos)

//////////////////////////////

/int

dep[n],siz[n],fa[n],son[n],head[m],pos,id[n],top[n],cnt;

struct

edge

edge[m];

void add(int a,int

b)void dfs1(int x,int f,int

deep)

}void dfs2(int x,int

topf)

}int qrange(int x,int y)//

詢問x到y最短路徑的權值和

if(dep[x]>dep[y])swap(x,y);

ans=(ans+query(id[x],id[y],1,n,1

));

return

ans;

}int qmax(int x,int

y)

if(dep[x]>dep[y])swap(x,y);

ans=max(ans,querymax(id[x],id[y],1,n,1

));

return

ans;

}int

main()

rep(i,

1,n)ri(node[i]);

dfs1(

1,0,1);dfs2(1,1

); build(

1,n,1

); ri(m);

rep(i,

1,m)

else

if(s=="

qsum

")

else rii(a,b),update(id[a],id[a],b,1,n,1

); }

return0;

}

view code

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