Problem - F - Codeforces
思路:这个题可以用树链剖分做,对于一个新加的黑节点来说,有两种情况,一种是往下走取得最小值,一种是往上走取得最小值,往下走的情况比较简单,就是取所有黑色子节点中的深度的最小值,减去当前节点的深度就是往下走能够取得的最小值,往上走能够取得的最小值假如说另一个点为v,那么最小值一定是d[u]+d[v]-2*d[lca(u,v)],我们能够维护d[v]-2*d[lca(u,v)],那么在查询时,只需要遍历从当前节点往父节点跳的重链,查询出最小的d[v]-2*d[lca(u,v)]即可,而在修改的时候,同样要按照重链往上跳,同时维护一下d[v]-2*d[lca(u,v)]
// Problem: F. Timofey and Black-White Tree
// Contest: Codeforces - Codeforces Round 847 (Div. 3)
// URL: https://codeforces.com/contest/1790/problem/F
// Memory Limit: 256 MB
// Time Limit: 4000 ms
#include
#include
#include
#define fi first
#define se second
#define i128 __int128
using namespace std;
typedef long long ll;
typedef double db;
typedef pair PII;
const double eps=1e-7;
const int N=5e5+7 ,M=5e5+7, INF=0x3f3f3f3f,mod=1e9+7,mod1=998244353;
const long long int llINF=0x3f3f3f3f3f3f3f3f;
inline ll read() {ll x=0,f=1;char c=getchar();while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=(ll)x*10+c-'0';c=getchar();} return x*f;}
inline void write(ll x) {if(x < 0) {putchar('-'); x = -x;}if(x >= 10) write(x / 10);putchar(x % 10 + '0');}
inline void write(ll x,char ch) {write(x);putchar(ch);}
void stin() {freopen("in_put.txt","r",stdin);freopen("my_out_put.txt","w",stdout);}
bool cmp0(int a,int b) {return a>b;}
template T gcd(T a,T b) {return b==0?a:gcd(b,a%b);}
template T lcm(T a,T b) {return a*b/gcd(a,b);}
void hack() {printf("\n----------------------------------\n");}
int T,hackT;
int n,m,k;
int vis[N];
int h[N],e[M],ne[M],idx;
int fa[N],son[N],dep[N],sum[N];
int top[N],id[N],cnt;
int nw[N];
int last[N];
void add(int a,int b) {
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs1(int u,int father,int d) {
sum[u]=1,dep[u]=d,fa[u]=father;
for(int i=h[u];i!=-1;i=ne[i]) {
int j=e[i];
if(j==father) continue;
dfs1(j,u,d+1);
sum[u]+=sum[j];
if(sum[son[u]]>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
pushup(u);
}
}
void modify_x(int u,int x) {
if(tr[u].l==x&&tr[u].r==x) {
tr[u].min1=tr[u].dep;
}else {
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(x<=mid) modify_x(u<<1,x);
else modify_x(u<<1|1,x);
pushup(u);
}
}
void modify_l_r(int u,int l,int r,int x) {
if(tr[u].l>=l&&tr[u].r<=r) {
tr[u].add=min(tr[u].add,x);
tr[u].min2=min(tr[u].min2,x-2*tr[u].dep);
}else {
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid) modify_l_r(u<<1,l,r,x);
if(r>mid) modify_l_r(u<<1|1,l,r,x);
pushup(u);
}
}
int query_1(int u,int l,int r) {
if(tr[u].l>=l&&tr[u].r<=r) return tr[u].min1;
else {
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
int res=INF;
if(l<=mid) res=min(res,query_1(u<<1,l,r));
if(r>mid) res=min(res,query_1(u<<1|1,l,r));
return res;
}
}
int query_2(int u,int l,int r) {
if(tr[u].l>=l&&tr[u].r<=r) return tr[u].min2;
else {
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
int res=INF;
if(l<=mid) res=min(res,query_2(u<<1,l,r));
if(r>mid) res=min(res,query_2(u<<1|1,l,r));
return res;
}
}
int qu2(int u) {
int res=INF;
while(u!=-1) {
res=min(res,query_2(1,id[top[u]],id[u]));
u=fa[top[u]];
}
return res;
}
void change2(int u,int temp) {
while(u!=-1) {
modify_l_r(1,id[top[u]],id[u],temp);
u=fa[top[u]];
}
}
void solve() {
n=read();
int co=read();
for(int i=1;i