题意:一棵树上有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