CF1413F Roads and Ramen 题解

时间:2021-09-06
本文章向大家介绍CF1413F Roads and Ramen 题解,主要包括CF1413F Roads and Ramen 题解使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Codeforces
Luogu

Description.

给定一个树,边带权 \(0,1\),支持单边翻转。
每次查询长度为 \(0\) 的链的最大值。

Solution.

首先我们发现了一个性质,答案路径必然经过直径一端。
详细证明参见这篇题解,感性理解的话就是从直径不断删一端的边。
然后就做完了,可以考虑维护单点的深度,然后支持区间乘上 \(-1\),查询区间最大值。

Coding.

点击查看乐瑟代码
//是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了{{{
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
	x=0;char c=getchar(),f=0;
	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	f?x=-x:x;
}
template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
const int N=500005;struct edge{int to,w,nxt;}e[N<<1];int et=1,head[N],id[N],Ca,q[N];
int n,d[N],ds[N],sz[N],dfn[N],dt,nfd[N],rs[N];struct segm{int mx,mn,fg;}T[N<<2];
inline void adde(int x,int y,int w) {e[++et]=(edge){y,w,head[x]},head[x]=et;}
inline void allc(int x) {swap(T[x].mx,T[x].mn),T[x].mx=-T[x].mx,T[x].mn=-T[x].mn,T[x].fg^=1;}
inline void pushdw(int x) {if(T[x].fg) allc(x<<1),allc(x<<1|1),T[x].fg=0;}
inline void pushup(int x) {T[x].mx=max(T[x<<1].mx,T[x<<1|1].mx),T[x].mn=min(T[x<<1].mn,T[x<<1|1].mn);}
inline void build(int x,int l,int r)
{
	T[x].fg=0;if(l==r) return T[x].mx=T[x].mn=d[nfd[l]],void();
	build(x<<1,l,(l+r)>>1),build(x<<1|1,((l+r)>>1)+1,r),pushup(x);
}
inline void modif(int x,int l,int r,int dl,int dr)
{
	if(l>dr||dl>r) return;else if(dl<=l&&r<=dr) return allc(x);else pushdw(x);
	modif(x<<1,l,(l+r)>>1,dl,dr),modif(x<<1|1,((l+r)>>1)+1,r,dl,dr),pushup(x);
}
inline void dfs0(int x,int fa)
{
	d[x]=d[fa]+1;for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=fa) dfs0(e[i].to,x);
}
inline void dfs1(int x,int fa)
{
	sz[x]=1,dfn[x]=++dt,nfd[dt]=x;for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=fa)
		ds[e[i].to]=ds[x]+e[i].w,dfs1(e[i].to,x),sz[x]+=sz[e[i].to],id[i>>1]=e[i].to;
}
inline void chg(int x) {x=id[x],modif(1,1,n,dfn[x],dfn[x]+sz[x]-1);}
inline void solve()
{
	int rt=0;for(int i=1;i<=n;i++) if(d[rt]<=d[i]) rt=i;
	dt=0,d[0]=-1,dfs0(rt,0),dfs1(rt,0),build(1,1,n);
	for(int i=1;i<n;i++) if(e[i<<1].w==1) chg(i);
	for(int i=1;i<=Ca;i++) chg(q[i]),rs[i]=max(rs[i],T[1].mx);
}
int main()
{
	read(n);for(int i=1,x,y,w;i<n;i++) read(x,y,w),adde(x,y,w),adde(y,x,w);
	dfs0(1,0);read(Ca);for(int i=1;i<=Ca;i++) read(q[i]);
	solve(),solve();for(int i=1;i<=Ca;i++) printf("%d\n",rs[i]);
	return 0;
}

原文地址:https://www.cnblogs.com/pealfrog/p/15235868.html