【BZOJ1036】树的统计Count(树链剖分)

题意:一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成
一些操作:

I. CHANGE u t : 把结点u的权值改为t

II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值

I

II. QSUM u v: 询问从点u到点v的路径上的节点的权值和

注意:从点u到点v的路径上的节点包括u和v本身

1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

思路:树链剖分,单点修改,区间查询和与最大值。

  1 var t1,t2,next,vet,head,dep,flag,tid,fa,top,size,id,son,a
  2    :array[1..200000]of longint;
  3     n,m,i,j,k,k1,t,x,y,tot,time,q,len,f:longint;
  4     ch:string;
  5
  6 procedure add(a,b:longint);
  7 begin
  8  inc(tot);
  9  next[tot]:=head[a];
 10  vet[tot]:=b;
 11  head[a]:=tot;
 12 end;
 13
 14 function max(x,y:longint):longint;
 15 begin
 16  if x>y then exit(x);
 17  exit(y);
 18 end;
 19
 20 procedure dfs1(u,fath,depth:longint);
 21 var e,v,maxsize:longint;
 22 begin
 23  flag[u]:=1; dep[u]:=depth; fa[u]:=fath;
 24  e:=head[u];
 25  flag[u]:=1; size[u]:=1;
 26  maxsize:=0; son[u]:=0;
 27  while e<>0 do
 28  begin
 29   v:=vet[e];
 30   if flag[v]=0 then
 31   begin
 32   // h[e]:=1;
 33    dfs1(v,u,depth+1);
 34    size[u]:=size[u]+size[v];
 35    if size[v]>maxsize then
 36    begin
 37     maxsize:=size[v];
 38     son[u]:=v;
 39    end;
 40   end;
 41   e:=next[e];
 42  end;
 43 end;
 44
 45 procedure dfs2(u,ance:longint);
 46 var e,v:longint;
 47 begin
 48  flag[u]:=1; inc(time); tid[u]:=time; id[time]:=u; top[u]:=ance;
 49  if son[u]>0 then dfs2(son[u],ance);
 50  e:=head[u];
 51  while e<>0 do
 52  begin
 53   v:=vet[e];
 54   if flag[v]=0 then dfs2(v,v);
 55   e:=next[e];
 56  end;
 57 end;
 58
 59 procedure build(l,r,p:longint);
 60 var mid:longint;
 61 begin
 62  if l=r then
 63  begin
 64   t1[p]:=a[id[l]];
 65   t2[p]:=a[id[l]];
 66   exit;
 67  end;
 68  mid:=(l+r)>>1;
 69  build(l,mid,p<<1);
 70  build(mid+1,r,p<<1+1);
 71  t1[p]:=max(t1[p<<1],t1[p<<1+1]);
 72  t2[p]:=t2[p<<1]+t2[p<<1+1];
 73 end;
 74
 75 procedure update(l,r,x,v,p:longint);
 76 var mid:longint;
 77 begin
 78  if l=r then
 79  begin
 80   t1[p]:=v; t2[p]:=v;
 81   exit;
 82  end;
 83  mid:=(l+r)>>1;
 84  if x<=mid then update(l,mid,x,v,p<<1);
 85  if x>mid then update(mid+1,r,x,v,p<<1+1);
 86  t1[p]:=max(t1[p<<1],t1[p<<1+1]);
 87  t2[p]:=t2[p<<1]+t2[p<<1+1];
 88 end;
 89
 90 function querymax(l,r,x,y,p:longint):longint;
 91 var mid,t:longint;
 92 begin
 93  if (l=x)and(r=y) then exit(t1[p]);
 94  mid:=(l+r)>>1;
 95  t:=-maxlongint;
 96  if y<=mid then t:=querymax(l,mid,x,y,p<<1)
 97   else if x>mid then t:=querymax(mid+1,r,x,y,p<<1+1)
 98   else t:=max(querymax(l,mid,x,mid,p<<1),querymax(mid+1,r,mid+1,y,p<<1+1));
 99  exit(t);
100 end;
101
102 function querysum(l,r,x,y,p:longint):longint;
103 var mid,t:longint;
104 begin
105  if (l=x)and(r=y) then exit(t2[p]);
106  mid:=(l+r)>>1;
107  t:=0;
108  if y<=mid then t:=querysum(l,mid,x,y,p<<1)
109   else if x>mid then t:=querysum(mid+1,r,x,y,p<<1+1)
110    else t:=querysum(l,mid,x,mid,p<<1)+querysum(mid+1,r,mid+1,y,p<<1+1);
111  exit(t);
112 end;
113
114 procedure swap(var x,y:longint);
115 var t:longint;
116 begin
117  t:=x; x:=y; y:=t;
118 end;
119
120 function askmax(x,y:longint):longint;
121 var f1,f2,t:longint;
122 begin
123  t:=-maxlongint;
124  f1:=top[x]; f2:=top[y];
125  while f1<>f2 do
126  begin
127   if dep[f1]<dep[f2] then
128   begin
129    swap(f1,f2); swap(x,y);
130   end;
131   t:=max(t,querymax(1,n,tid[f1],tid[x],1));
132   x:=fa[f1]; f1:=top[x];
133  end;
134  if dep[x]>dep[y] then swap(x,y);
135  t:=max(t,querymax(1,n,tid[x],tid[y],1));
136  exit(t);
137 end;
138
139 function asksum(x,y:longint):longint;
140 var f1,f2,t:longint;
141 begin
142  t:=0;
143  f1:=top[x]; f2:=top[y];
144  while f1<>f2 do
145  begin
146   if dep[f1]<dep[f2] then
147   begin
148    swap(f1,f2); swap(x,y);
149   end;
150   t:=t+querysum(1,n,tid[f1],tid[x],1);
151   x:=fa[f1]; f1:=top[x];
152  end;
153  if dep[x]>dep[y] then swap(x,y);
154  t:=t+querysum(1,n,tid[x],tid[y],1);
155  exit(t);
156 end;
157
158 begin
159  //assign(input,‘bzoj1036.in‘); reset(input);
160  //assign(output,‘bzoj1036.out‘); rewrite(output);
161  readln(n);
162  for i:=1 to n-1 do
163  begin
164   readln(x,y);
165   add(x,y);
166   add(y,x);
167  end;
168  for i:=1 to n do read(a[i]);
169  dfs1(1,-1,1);
170  fillchar(flag,sizeof(flag),0);
171  dfs2(1,1);
172  fillchar(t1,sizeof(t1),$8f);
173  build(1,n,1);
174  readln(q);
175  for i:=1 to q do
176  begin
177   readln(ch);
178   x:=0; y:=0;
179   for j:=1 to length(ch) do
180    if ch[j]=‘ ‘ then break;
181   while ch[j]=‘ ‘ do inc(j);
182   f:=1;
183   while ch[j]<>‘ ‘ do
184   begin
185   // if ch[j]=‘-‘ then f:=-1;
186    if (ch[j]>=‘0‘)and(ch[j]<=‘9‘) then x:=x*10+ord(ch[j])-ord(‘0‘);
187    inc(j);
188   end;
189
190   while ch[j]=‘ ‘ do inc(j);
191   while (j<=length(ch))and(ch[j]<>‘ ‘) do
192   begin
193    if ch[j]=‘-‘ then f:=-1;
194    if (ch[j]>=‘0‘)and(ch[j]<=‘9‘) then y:=y*10+ord(ch[j])-ord(‘0‘);
195    inc(j);
196   end;
197   if f=-1 then y:=-y;
198
199
200
201   if ch[1]=‘C‘ then update(1,n,tid[x],y,1);
202   if (ch[1]=‘Q‘)and(ch[2]=‘M‘) then writeln(askmax(x,y));
203   if (ch[1]=‘Q‘)and(ch[2]=‘S‘) then writeln(asksum(x,y));
204  {  if ch[1]=‘C‘ then
205   begin
206    delete(ch,1,7);
207    val(copy(ch,1,pos(‘ ‘,ch)-1),x);
208    val(copy(ch,pos(‘ ‘,ch)+1,length(ch)-pos(‘ ‘,ch)),y);
209    update(1,n,tid[x],y,1);
210   end
211    else if ch[2]=‘M‘ then
212    begin
213     delete(ch,1,5);
214     val(copy(ch,1,pos(‘ ‘,ch)-1),x);
215     val(copy(ch,pos(‘ ‘,ch)+1,length(ch)-pos(‘ ‘,ch)),y);
216     writeln(askmax(x,y));
217    end
218     else
219     begin
220      delete(ch,1,5);
221      val(copy(ch,1,pos(‘ ‘,ch)-1),x);
222      val(copy(ch,pos(‘ ‘,ch)+1,length(ch)-pos(‘ ‘,ch)),y);
223      writeln(asksum(x,y));
224
225     end;    }
226
227  end;
228  //close(input);
229  //close(output);
230 end.
时间: 2024-10-29 19:10:59

【BZOJ1036】树的统计Count(树链剖分)的相关文章

HYSBZ - 1036 树的统计Count 树链剖分 求和+最大值

好水0.0 #include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<set> #include<map> #include<queue> #include<vector> #include<string> #define eps 1e-12 #de

【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分

[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有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本身 Input 输入的第一行为一个整数n,表示节点的个数.接下来n

bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题

[ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I II. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身 Input 输入的第一行为一个整数n,表示节点的个数.接下来n – 1行,每行

BZOJ1036: [ZJOI2008]树的统计Count - 树链剖分 -

1036: [ZJOI2008]树的统计Count Description 一棵树上有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本身 Input 输入的第一行为一个整数n,表示节点的个数.接下来n – 1

BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)

1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14982  Solved: 6081[Submit][Status][Discuss] Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I

BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]

1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14302  Solved: 5779[Submit][Status][Discuss] Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I

BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分)(线段树单点修改)

[ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14968  Solved: 6079[Submit][Status][Discuss] Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I II.

bzoj 1036 [ZJOI2008]树的统计Count 树链剖分模板

1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 18615  Solved: 7598[Submit][Status][Discuss] Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I

[BZOJ1036/ZJOI2008]树的统计(Count)-树链剖分

Problem 树的统计 题目大意 一棵树上有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本身 So Lazy No Solution 裸的树链剖分,题解一搜一大把.就连这个都炸了几次.我太菜了... AC

【BZOJ1036】【ZJOI2008】树的统计Count 树链剖分裸题

题解:裸的,没什么好说的. 树链剖分不会的先理解一下重链轻链,然后直接扒我代码理解就行了. 贴代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 30100 #define inf 0x3f3f3f3f using namespace std; struct KSD { int u,v,next; }e[N<<1];