Description

Link.

给出一棵树,初始边权为 \(0\),支持毛毛虫虫体赋 \(1\),虫足赋 \(0\),以及查询路径边权和操作,\(n,m\leqslant 10^5\)。

Solution

立马想到按时间染色,那么判定一条边 \((u,v)\) 为重边的充要条件即 \(col(u)=col(v)\)(初始每个节点的颜色为 \(1,\dots,n\))。

然后修改就转化为链覆盖,查询就成了查询区间相邻颜色相同二元组个数。HLD & 线段树可以解决。

说一下线段树的维护方法,维护区间左端点颜色、右端点颜色以及相邻颜色相同二元组个数(还有区间覆盖懒标)。向上 / 下更新均显。

因为整篇题解加起来还没有代码长,所以为避免头轻脚重折叠了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++);
char buf[1<<21],*p1=buf,*p2=buf;
inline ll read() {
ll x=0,f=0; char ch=getchar();
while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+(ch&15),ch=getchar();
return f?-x:x;
}
const int N=100100;
vector<int> G[N];
int n,m,dep[N],son[N],top[N],fa[N],sz[N],dfn[N],sjc,ton[N],col[N],cnt;
struct node { int lc,rc,num,tag; } tr[N*4],emp;
void push_up(int now) {
tr[now].lc=tr[now<<1].lc;
tr[now].rc=tr[now<<1|1].rc;
tr[now].num=tr[now<<1].num+tr[now<<1|1].num+(tr[now<<1].rc==tr[now<<1|1].lc);
}
void push_down(int now,int l,int r) {
if(!tr[now].tag) return;
int mid=(l+r)>>1;
tr[now<<1].num=mid-l,tr[now<<1|1].num=r-mid-1;
tr[now<<1].lc=tr[now<<1|1].lc=tr[now].tag;
tr[now<<1].rc=tr[now<<1|1].rc=tr[now].tag;
tr[now<<1].tag=tr[now<<1|1].tag=tr[now].tag;
tr[now].tag=0;
}
void build(int l,int r,int now) {
tr[now]=emp;
if(l==r) return ++cnt,tr[now]=node{cnt,cnt,0,0},void();
int mid=(l+r)>>1;
build(l,mid,now<<1),build(mid+1,r,now<<1|1);
push_up(now);
}
void ins(int l,int r,int now,int x,int y,int v) {
if(l>y||r<x) return;
if(l>=x&&r<=y) return tr[now].tag=tr[now].lc=tr[now].rc=v,tr[now].num=r-l,void();
int mid=(l+r)>>1;
push_down(now,l,r);
ins(l,mid,now<<1,x,y,v),ins(mid+1,r,now<<1|1,x,y,v);
push_up(now);
}
int find0(int l,int r,int now,int x,int y) {
if(l>=x&&r<=y) return tr[now].num;
int mid=(l+r)>>1,res=0;
push_down(now,l,r);
if(mid>=x) res+=find0(l,mid,now<<1,x,y);
if(mid<y) res+=find0(mid+1,r,now<<1|1,x,y);
return res+(x<=mid&&y>mid&&tr[now<<1].rc==tr[now<<1|1].lc);
}
int find1(int l,int r,int now,int x) {
if(l==r) return tr[now].lc;
int mid=(l+r)>>1;
push_down(now,l,r);
return mid>=x?find1(l,mid,now<<1,x):find1(mid+1,r,now<<1|1,x);
}
void clear(int l,int r,int now) {
tr[now]=emp;
if(l==r) return;
int mid=(l+r)>>1;
clear(l,mid,now<<1),clear(mid+1,r,now<<1|1);
}
signed main() {
function<void(int,int)> dfs0=[&](int x,int las) {
fa[x]=las,dep[x]=dep[las]+1,sz[x]=1;
for(int y:G[x]) if(y!=las) dfs0(y,x),sz[x]+=sz[y],(sz[y]>sz[son[x]])&&(son[x]=y);
};
function<void(int,int,int)> dfs1=[&](int x,int las,int t) {
top[x]=t,ton[dfn[x]=++sjc]=x;
if(son[x]) dfs1(son[x],x,t);
for(int y:G[x]) if(y!=las&&y!=son[x]) dfs1(y,x,y);
};
for(int Case=read(); Case; --Case) {
n=read(),m=read();
for(int i=1,x,y; i<n; ++i) x=read(),y=read(),G[x].push_back(y),G[y].push_back(x);
dfs0(1,0),dfs1(1,0,1),build(1,n,1);
for(int t,x,y; m; --m) {
t=read(),x=read(),y=read();
if(t==1) {
++cnt;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ins(1,n,1,dfn[top[x]],dfn[x],cnt);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ins(1,n,1,dfn[x],dfn[y],cnt);
} else {
int res=0;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res+=find0(1,n,1,dfn[top[x]],dfn[x])+(find1(1,n,1,dfn[top[x]])==find1(1,n,1,dfn[fa[top[x]]]));
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
res+=find0(1,n,1,dfn[x],dfn[y]);
printf("%d\n",res);
}
}
for(int i=1; i<=n; ++i) dep[i]=son[i]=top[i]=fa[i]=sz[i]=dfn[i]=ton[i]=0,G[i].clear();
sjc=cnt=0,clear(1,n,1);
}
return 0;
}

Solution -「NOI 2021」轻重边的更多相关文章

  1. Solution -「NOI 2021」「洛谷 P7740」机器人游戏

    \(\mathcal{Description}\)   Link.   自己去读题面叭~ \(\mathcal{Solution}\)   首先,参悟[样例解释 #2].一种暴力的思路即为钦定集合 \ ...

  2. Diary -「NOI 2021」酱油记

    雨幕浓稠 远近一白 是水雾弥漫的天 还是泡沫撑起的海   雨真大呢.   前几天去 ZH 中学集训没啥好记的,就从会合日开始叭. [Day -1]   逃出 ZH,掉入梦麟.(   高中的同学们忘记带 ...

  3. Solution -「JOISC 2021」古老的机器

    \(\mathcal{Description}\)   Link.   这是一道通信题.   对于长度为一个 \(n\),仅包含字符 X, Y, Z 的字符串 \(s\),将其中 \(n\) 个字符按 ...

  4. Solution -「JOISC 2021」「LOJ #3489」饮食区

    \(\mathcal{Description}\)   Link.   呐--不想概括题意,自己去读叭~ \(\mathcal{Solution}\)   如果仅有 1. 3. 操作,能不能做?    ...

  5. Solution -「JOISC 2021」「LOJ #3495」聚会 2

    \(\mathcal{Description}\)   Link.   给定一棵含 \(n\) 个结点的树.称点集 \(S\) 到结点 \(u\) 的会合距离为 \(\sum_{v\in S}\ope ...

  6. Solution -「JOISC 2021」「LOJ #3491」道路建设

    \(\mathcal{Description}\)   Link.   平面上有 \(n\) 个互不重合的点 \((x_{1..n},y_{1..n})\),求其两两曼哈顿距离的前 \(m\) 小值. ...

  7. Solution -「NOI 2020」「洛谷 P6776」超现实树

    \(\mathcal{Description}\)   Link.   对于非空二叉树 \(T\),定义 \(\operatorname{grow}(T)\) 为所有能通过若干次"替换 \( ...

  8. Solution -「NOI 2016」「洛谷 P1587」循环之美

    \(\mathcal{Description}\)   Link.   给定 \(n,m,k\),求 \(x\in [1,n]\cap\mathbb N,y\in [1,m]\cap \mathbb ...

  9. Solution -「NOIOL-S 2021」「洛谷 P7470」岛屿探险

    \(\mathcal{Description}\)   Link.   给定序列 \(\{(a,b)_n\}\),\(q\) 组形如 \((l,r,c,d)\) 的询问,求 \[\Big|\{i\in ...

  10. Solution -「NOI 2012」「洛谷 P2050」美食节

    \(\mathcal{Description}\)   Link.   美食节提供 \(n\) 种菜品,第 \(i\) 种的需求量是 \(p_i\),菜品由 \(m\) 个厨师负责制作,第 \(j\) ...

随机推荐

  1. NOIP2021游记

    前言: 今年我是以初中生的身份参加的 NOIP,不计奖,不排名,就去试试水. 考得也不好,幸好没计奖. 正文: 早上 7 点: 到LNBS,在旁边吃了早饭,很好吃. 早上 8 点: 校门口照相,然后进 ...

  2. 大型 3D 互动开发和优化实践

    开发背景 得益于"元宇宙"概念在前段时间的爆火,各家公司都推出了使用 3D 场景的活动或频道. 3D 场景相比传统的 2D 页面优点是多一个维度,同屏展示的内容可以更多,能完整的展 ...

  3. .Net8罕见的技术:MSIL的机器码简析

    前言 一般的只有最终的汇编代码才有机器码表示,然一个偶然的机会发现,MSIL(Microsoft intermediate language)作为一个中间语言表示,居然也有机器码,其实这也难怪,计算机 ...

  4. java利用jni调用dll方法

    准备工作: 需要用到的插件jni4net:这个需要去官网下载:https://sourceforge.net/projects/jni4net/files/ (1)     jni4net 是一个开源 ...

  5. 【电脑Tips】Win11自动更新之后开机黑屏

    目录 0.问题描述 1. 释放静电 具体操作 效果 参考博客 2. 运行explorer.exe 具体操作: [问题]:如何打开任务管理器? 效果 参考博客 另外的运行方法 3. 禁用APP Read ...

  6. StencilJs 学习之 JSX

    Stencil 组件使用 JSX 渲染,这是一种流行的声明式模板语法.每个组件都有一个渲染函数,它返回在运行时渲染到 DOM 的组件树. 基础用法 render 函数用于输出将绘制到屏幕上的组件树. ...

  7. 快上车,搭乘HUAWEI HiCar驶向未来

    HUAWEI HiCar(以下简称HiCar)是华为提供的人-车-家全场景智慧互联解决方案,连接手机与车辆,充分发挥各自的优势属性,将手机的应用/服务生态延伸进车辆,实现以手机为核心的全场景体验.消费 ...

  8. 完美决解win10 可以上网却显示无internet的bug

    试过网上的几乎所有方法,例如禁用复用网卡.网络重置.禁用复用服务,也用了用修改注册表下HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesNlaSvcPa ...

  9. CentOS上安装Redis的两种方式

    今天小编给大家介绍下,如何在CentOS上安装Redis.通常有两种方式:第一种是通过下载源码并编译来安装,第二种是通过仓库直接安装.相较而言,第二种方式更直截了当,但小编更倾向第一种. 一.通过源码 ...

  10. 深度系统安装wine

    step1: 输入命令: sudo dpkg --add-architecture i386 step2: 1.切换成管理员权限: sudo su 2.打开源文件 vi /etc/apt/source ...