题解:P16445 [XJTUPC 2026] The Whole Rest

· · 题解

赛时首杀。

如果一条路径起点为 s 终点为 t,拉出 st 的简单路径。因为是树,所以不在 st 路径上的边一定经过偶数次,即路径的代价为起点到终点简单路径的异或和。

考虑一条回路,路径的代价为 0,所以最小值一定是 0。当确定了起点和终点,最优路径一定是从起点走到终点,途中按 dfs 序遍历不在简单路径上的点。

令 $D_u=\operatorname{dis}(1,u)$,要求找最长的、$D_s=D_t$ 的 $(s,t)$。把 $D$ 相同的点放到一起,又转化为找每个 $D$ 值虚树的直径。直接对每个 $D$ 值找离 $1$ 最远的点,再找离这个点最远的点即可。 :::info[代码] ```cpp #include<bits/stdc++.h> #define il inline #define ui unsigned int #define ll long long #define ull unsigned ll #define lll __int128 #define db double #define ldb long double #define pii pair<int,int> #define vi vector<int> #define vpii vector<pii> #define fir first #define sec second #define gc getchar #define pc putchar #define pb push_back #define lb lower_bound #define ub upper_bound #define pct __builtin_popcount #define mst(a,x) memset(a,x,sizeof a) #define mcp(a,b) memcpy(a,b,sizeof b) using namespace std; const int N=5e5+10,INF=0x3f3f3f3f,MOD=998244353; const ll INFll=0x3f3f3f3f3f3f3f3f; il int rd() {int x=0,f=1; char ch=gc(); while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=gc();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc(); return x*f;} il ll rdll() {ll x=0; int f=1; char ch=gc(); while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=gc();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc(); return x*f;} il void wr(int x) {if(x==INT_MIN) return printf("-2147483648"),void(); if(x<0) return pc('-'),wr(-x); if(x<10) return pc(x+'0'),void(); wr(x/10),pc(x%10+'0');} il void wrll(ll x) {if(x==LLONG_MIN) return printf("-9223372036854775808"),void(); if(x<0) return pc('-'),wrll(-x); if(x<10) return pc(x+'0'),void(); wrll(x/10),pc(x%10+'0');} il void wr(int x,const char *s) {wr(x),printf("%s",s);} il void wrll(ll x,const char *s) {wrll(x),printf("%s",s);} il int vmod(int x) {return x>=MOD?x-MOD:x;} il int vadd(int x,int y) {return vmod(x+y);} il int vsub(int x,int y) {return vmod(x-y+MOD);} il int vmul(int x,int y) {return 1ll*x*y%MOD;} il int qpow(int x,int y) {int r=1; for(;y;y>>=1,x=vmul(x,x)) if(y&1) r=vmul(r,x); return r;} il void cadd(int &x,int y) {x=vmod(x+y);} il void csub(int &x,int y) {x=vmod(x-y+MOD);} il void cmul(int &x,int y) {x=vmul(x,y);} il void cmax(int &x,int y) {x<y&&(x=y);} il void cmaxll(ll &x,ll y) {x<y&&(x=y);} il void cmin(int &x,int y) {x>y&&(x=y);} il void cminll(ll &x,ll y) {x>y&&(x=y);} int n,id=1,mn=INF,hd[N],ds[N],ac[N][20],d[N]; struct EDGE {int to,w,ne;} e[N*2]; il void add(int u,int v,int w) {e[++id]={v,w,hd[u]},hd[u]=id;} void dfs1(int u,int fa) { ac[u][0]=fa,d[u]=d[fa]+1; for(int i=1;i<20;i++) ac[u][i]=ac[ac[u][i-1]][i-1]; for(int i=hd[u],v;i;i=e[i].ne) if((v=e[i].to)!=fa) ds[v]=ds[u]^e[i].w,dfs1(v,u); } int ln,dd[N],ps[N],md[N]; vi vc[N]; int lca(int u,int v) { if(d[u]<d[v]) swap(u,v); for(int i=19;~i;i--) if(d[ac[u][i]]>=d[v]) u=ac[u][i]; if(u==v) return u; for(int i=19;~i;i--) if(ac[u][i]!=ac[v][i]) u=ac[u][i],v=ac[v][i]; return ac[u][0]; } int as=-1,s,t,bk[N],fg[N*2]; void dfs2(int u,int fa) { bk[u]=u==t; for(int i=hd[u],v;i;i=e[i].ne) if((v=e[i].to)!=fa) { dfs2(v,u); if(bk[v]) bk[u]=1,fg[i]=fg[i^1]=1; } } vi sq; void dfs3(int u,int fa) { sq.pb(u); for(int i=hd[u],v;i;i=e[i].ne) if((v=e[i].to)!=fa&&!fg[i]) dfs3(v,u),sq.pb(u); for(int i=hd[u],v;i;i=e[i].ne) if((v=e[i].to)!=fa&&fg[i]) dfs3(v,u); } void QwQ() { n=rd(); for(int i=1,u,v,w;i<n;i++) u=rd(),v=rd(),w=rd(),add(u,v,w),add(v,u,w); dfs1(1,0); for(int i=1;i<=n;i++) dd[i]=ds[i]; sort(dd+1,dd+1+n),ln=unique(dd+1,dd+1+n)-dd-1; for(int i=1;i<=n;i++) { int x=lb(dd+1,dd+1+ln,ds[i])-dd; vc[x].pb(i); if(md[x]<d[i]+1) md[x]=d[i]+1,ps[x]=i; } for(int i=1;i<=ln;i++) { int u=ps[i],x=lb(dd+1,dd+1+ln,ds[u])-dd; for(int j:vc[x]) { int cr=d[u]+d[j]-d[lca(u,j)]*2; if(as<cr) as=cr,s=u,t=j; } } dfs2(s,0),dfs3(s,0); if(sq.back()!=t) sq.pb(t); wr(sq.size(),"\n"); for(int x:sq) wr(x," "); } signed main() { // freopen("in.in","r",stdin),freopen("out.out","w",stdout); int T=1; while(T--) QwQ(); } /* 4 1 2 0 2 3 0 2 4 1 */ ``` :::