A 最近点对
不会
B 最长路径
显然有dist(u) + dist(v) - 2dist(LCA(u,v))=dis(u) xor dis(v)(+- 都是 xor),然后就变成一堆数选两个xor最大,题解是字典树做的(似乎二叉的字典树也不好写啊),我就二分做了(似乎也不好做)。一开始build只加了一个方向,囧。
Codeprogram path; uses math; const maxn=200000;len=29; var d,mid,ans,tot,root,n,x,y,z,i,j,u,h,t,a,b,l,r,query:longint; v,next,w:array[0..maxn*2] of longint; Q,dis,Adjlist:array[1..maxn] of longint; vis:array[1..maxn] of boolean; procedure build(x,y,z:longint); begin inc(tot); v[tot]:=y;w[tot]:=z; next[tot]:=Adjlist[x]; Adjlist[x]:=tot; end; procedure swap(var x,y:longint); var t:longint; begin t:=x;x:=y;y:=t;end; procedure Qsort(l,r:longint); var i,j,mid:longint; begin i:=l;j:=r;mid:=dis[(l+r)>>1]; repeat while(i<r)and(dis[i]<mid)do inc(i); while(l<j)and(mid<dis[j])do dec(j); if i<=j then begin swap(dis[i],dis[j]); inc(i);dec(j); end; until i>j; if(l<j)then Qsort(l,j); if(i<r)then Qsort(i,r); end; begin assign(input,'path.in'); assign(output,'path.out'); reset(input);rewrite(output); readln(n); for i:=1 to n-1 do begin readln(x,y,z); build(x,y,z); build(y,x,z); end; root:=1; vis[root]:=true; h:=0;t:=1;Q[1]:=root; while h<t do begin inc(h);u:=Q[h]; i:=Adjlist[u]; while i<>0 do begin if not vis[v[i]] then begin inc(t);Q[t]:=v[i]; dis[v[i]]:=dis[u] xor w[i]; vis[v[i]]:=true; end; i:=next[i];end; end; Qsort(1,n); for i:=1 to n do begin a:=1;b:=n;query:=dis[i]; for d:=len downto 0 do begin l:=a;r:=b; if((dis[l]>>d)and 1)=1 then r:=a; if((dis[r]>>d)and 1)=0 then l:=b; while l<r-1 do begin mid:=(l+r)>>1; if boolean((dis[mid]>>d)and 1) then r:=mid else l:=mid; end; if(boolean((Query>>d)and 1)) then begin if a<r then b:=l;end else begin if l<b then a:=r;end; end; ans:=max(max(Query xor dis[l],Query xor dis[r]),ans); end; writeln(ans); close(input);close(output); end.
C 山蜂
容斥+装压DP,我无力了。