牛客练习赛108 E.琉焰(非树边性质/线段树分治+可撤销并查集 or LCT)

news2024/9/21 14:49:10

题目

 

思路来源

官方题解

题解

针对每个连通块,单独考虑:

一方面,

任取连通块的某棵生成树,

对于任意非树边(u,v),把树边u到v上的所有边都选中,即被覆盖1次,

任取某个非树边集合S,会导致树边有些被覆盖奇数次,有些被覆盖偶数次,

仅保留覆盖奇数次的树边,连通块内的点的度数就均为偶数了

另一方面,

度数为偶数的点有欧拉回路,

可以取走一个环,使得剩下的边仍然满足存在欧拉回路的条件,

即欧拉回路可以被拆成若干个环,并与刚才选取非树边时所取的环的方式一一对应

所以,答案即为所有非树边任取非空子集,

即若非树边条数为x,答案为2^{x}-1

由于涉及到类似图的连通块的动态维护,可以在线LCT做

也可以离线下来线段树分治+可撤销并查集做,

非树边即为成环边,即并查集合并时已经在同一个集合里的边,维护其条数tot即可

代码

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define lson p<<1,l,mid
#define rson p<<1|1,mid+1,r
using namespace std;
typedef long long ll;
const int maxn=2e5,N=maxn+10,mod=998244353;
typedef pair<int,int> P;
map<P,int> last;
vector<P>dat[4*N];
int n,m,cnt,par[N],sz[N];
P a;
int tot,ans[N],two[N];
int find(int x){
	return par[x]==x?x:find(par[x]);
}
bool merge(int x,int y,stack<P> &q){
	x=find(x),y=find(y);
	if(x==y)return 1;
	if(sz[x]<sz[y])swap(x,y);
	q.push(P(x,y));
	sz[x]+=sz[y];
	par[y]=x;
    return 0;
}
void undo(stack<P> &q){
	while(!q.empty()){
		int x=q.top().fi;
		int y=q.top().se;
		q.pop();
		sz[x]-=sz[y];
		par[y]=y;
	} 
} 
void update(int p,int l,int r,int ql,int qr,P v){
	if(ql<=l&&r<=qr){
		dat[p].pb(v);
		return;
	}
	int mid=(l+r)/2;
	if(ql<=mid)update(lson,ql,qr,v);
	if(qr>mid)update(rson,ql,qr,v);
}
void dfs(int p,int l,int r){
	stack<P>q;
    int cnt=0;
	for(auto v:dat[p])
	cnt+=merge(v.fi,v.se,q); // 非树边的数量的变更
	tot+=cnt;
    if(l==r)ans[l]=two[tot]-1;
	else{
		int mid=(l+r)/2;
		dfs(lson);
		dfs(rson);
	}
	undo(q);
    tot-=cnt;
}
int main(){
	scanf("%d%d",&n,&m);
    two[0]=1;
	for(int i=1;i<=m;++i){
        two[i]=two[i-1]*2%mod;
		scanf("%d%d",&a.fi,&a.se);
		if(last.count(a)){
			update(1,1,m,last[a],i-1,a);
			last.erase(a); 
		}
		else last[a]=i;
	}
	for(auto v:last) 
	update(1,1,m,v.se,m,v.fi);
	for(int i=1;i<=m;++i)
	par[i]=i,sz[i]=1;
	dfs(1,1,m);
	for(int i=1;i<=m;++i)
	printf("%d\n",ans[i]);
	return 0;
}#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define lson p<<1,l,mid
#define rson p<<1|1,mid+1,r
using namespace std;
typedef long long ll;
const int maxn=2e5,N=maxn+10,mod=998244353;
typedef pair<int,int> P;
map<P,int> last;
vector<P>dat[4*N];
int n,m,cnt,par[N],sz[N];
P a;
int tot,ans[N],two[N];
int find(int x){
	return par[x]==x?x:find(par[x]);
}
bool merge(int x,int y,stack<P> &q){
	x=find(x),y=find(y);
	if(x==y)return 1;
	if(sz[x]<sz[y])swap(x,y);
	q.push(P(x,y));
	sz[x]+=sz[y];
	par[y]=x;
    return 0;
}
void undo(stack<P> &q){
	while(!q.empty()){
		int x=q.top().fi;
		int y=q.top().se;
		q.pop();
		sz[x]-=sz[y];
		par[y]=y;
	} 
} 
void update(int p,int l,int r,int ql,int qr,P v){
	if(ql<=l&&r<=qr){
		dat[p].pb(v);
		return;
	}
	int mid=(l+r)/2;
	if(ql<=mid)update(lson,ql,qr,v);
	if(qr>mid)update(rson,ql,qr,v);
}
void dfs(int p,int l,int r){
	stack<P>q;
    int cnt=0;
	for(auto v:dat[p])
	cnt+=merge(v.fi,v.se,q); // 非树边的数量的变更
	tot+=cnt;
    if(l==r)ans[l]=two[tot]-1;
	else{
		int mid=(l+r)/2;
		dfs(lson);
		dfs(rson);
	}
	undo(q);
    tot-=cnt;
}
int main(){
	scanf("%d%d",&n,&m);
    two[0]=1;
	for(int i=1;i<=m;++i){
        two[i]=two[i-1]*2%mod;
		scanf("%d%d",&a.fi,&a.se);
		if(last.count(a)){
			update(1,1,m,last[a],i-1,a);
			last.erase(a); 
		}
		else last[a]=i;
	}
	for(auto v:last) 
	update(1,1,m,v.se,m,v.fi);
	for(int i=1;i<=m;++i)
	par[i]=i,sz[i]=1;
	dfs(1,1,m);
	for(int i=1;i<=m;++i)
	printf("%d\n",ans[i]);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/675434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LangChain for LLM Application Development 基于LangChain开发大语言应用模型(下)

以下内容均整理来自deeplearning.ai的同名课程 Location 课程访问地址 DLAI - Learning Platform Beta (deeplearning.ai) LangChain for LLM Application Development 基于LangChain开发大语言应用模型&#xff08;上&#xff09; 一、LangChain: Q&A over Documents基于文…

bert4rec简介

1、bert4rec提出动机 用户行为动态变化&#xff0c;序列行为建模取得了不错的效果 单向结构限制了行为序列中隐藏信息的挖掘 序列神经网络顺序依赖&#xff0c;无法并行计算 为此&#xff0c;提出了 基于双向self-attention和Cloze task的用户行为序列建模方法。据我们所知…

解决Jenkins报错

解决Jenkins报错 1 linux空间不够问题1.1 报错现象1.2 定位问题1.3 解决措施 2 bash问题2.1 问题现象2.2 问题定位2.3 解决措施 3 虚拟环境问题3.1 问题现象3.2 问题定位3.3 解决措施 4 jenkins构建完成但一直转圈问题4.1 问题现象4.2 问题定位4.3 解决措施 5 jenkins自动化部署…

C高级6.24

一、整理grep、find、cut、tar、apt-get、dpkg、ln、ln-s指令 1.grep ----->查找字符串 grep 字符串 文件名 -w:按单词查找 -R:实现递归查找&#xff0c;主要用于路径是目录的情况 -i:不区分大小写 -n:显示行号 grep -w "^ubuntu" /etc/passwd ---->查找以ub…

【深度学习】RepVGG解析和学习体会

文章目录 前言0. Vgg1.RepVGG Block 详解 前言 论文名称&#xff1a;RepVGG: Making VGG-style ConvNets Great Again 论文下载地址&#xff1a;https://arxiv.org/abs/2101.03697 官方源码&#xff08;Pytorch实现&#xff09;&#xff1a;https://github.com/DingXiaoH/RepV…

今天是世界Wi-Fi日!

很多人都不知道&#xff0c;今天其实是世界Wi-Fi日&#xff1a; 这个特殊的纪念日&#xff0c;是由无线宽带联盟&#xff08;Wireless Broadband Alliance&#xff09;确定的&#xff0c;并得到了互联城市咨询委员会 &#xff08;CCAB&#xff09;等组织的大力支持。 无线宽带联…

数据处理神器tidyverse!教你如何秒速搞定数据处理!

一、前言 在R语言中&#xff0c;tidyverse是一个庞大的数据分析生态系统&#xff0c;它由一系列数据可视化和数据处理软件包组成&#xff0c;能够极大地提高数据分析的效率和准确性。 在使用 Tidyverse 的过程中&#xff0c;我们会经常用到以下几个工具&#xff1a; ggplot2&am…

chatgpt赋能python:Python浮点数:介绍、精度和应用

Python浮点数&#xff1a;介绍、精度和应用 Python是一种高级编程语言&#xff0c;许多程序员使用Python编写计算机程序。与其他编程语言不同&#xff0c;Python是一种动态类型的语言&#xff0c;并且它处理浮点数时更加灵活。在本文中&#xff0c;我们将介绍Python浮点数的概…

python自动化办公——读取PPT写入word表格

Python自动化办公——读取PPT内容写入word表格 文章目录 Python自动化办公——读取PPT内容写入word表格一、需求分析二、导入依赖三、代码四、结果及总结 一、需求分析 &#x1f4d6;由于我们知识图谱课程需要将课堂小组汇报的PPT总结成word文档&#xff0c;而我觉得一页一页复…

win10安装nginx的配置和使用方法(图文)

window10系统安装nginx服务&#xff0c;提供网页方面的服务。下面为详细图文安装配置教程。 1&#xff09;下载nginx软件 官方下载地址&#xff1a;http://nginx.org/en/download.html 2&#xff09;解压缩软件 unzip nginx-1.20.1.zip 或者 使用解压缩软件&#xff0c;下…

视频与AI,与进程交互(二) pytorch 极简训练自己的数据集并识别

目标学习任务 检测出已经分割出的图像的分类 2 使用pytorch pytorch 非常简单就可以做到训练和加载 2.1 准备数据 如上图所示&#xff0c;用来训练的文件放在了train中&#xff0c;验证的文件放在val中&#xff0c;train.txt 和 val.txt 分别放文件名称和分类类别&#xff…

Android之 弹框总结

一 简介 1.1 弹框即浮与页面之上的窗口&#xff0c;如键盘弹框&#xff0c;吐司弹框&#xff0c;确认弹框&#xff0c;下拉选择框&#xff0c;应用悬浮框等 1.2 弹框控件也很多&#xff0c;比如常用的Spinner&#xff0c;Dialog&#xff0c;Toast&#xff0c;PopWindow等&…

小主机折腾记14

1.m72e主机&#xff0c;3240t-2390t-3470t测试&#xff1b; 2390t官方参数 在m72e上 全核3.08Ghz 单核3.28-3.31Ghz 核显2帧 评分 3470t官方参数 在m72e上 全核睿频3.28 单核最高3.44 核显1.2帧&#xff1f;&#xff1f;&#xff1f;还不如那啥HD2000 最后评分 进入…

chatgpt赋能python:Python求累加的方法及其应用

Python求累加的方法及其应用 在Python编程中&#xff0c;经常需要对一系列数字进行求和或累加的操作。那么在Python中&#xff0c;我们可以通过哪些方法来实现这个功能呢&#xff1f;本文将为大家介绍Python求累加的方法及其应用。 1. Python中的for循环 首先&#xff0c;我…

05-事件循环

事件循环 以下知识点都涉及到事件循环 计时器&#xff0c;promise&#xff0c;ajax&#xff0c;node 明白此知识点&#xff0c;是前端的分水岭&#xff0c;可以提高效率&#xff0c;js中奇怪的东西都可以得到解决&#xff0c;整个过程是根据W3C和谷歌源码进行 浏览器的进程…

一文理解cast转换

目录 写在前边 1. what&#xff1f;又报错&#xff1a; 2. 靠&#xff0c;难道是这样&#xff1f; 3. 小试牛刀 4. 实际中的“坑” 写在后边 写在前边 关于$cast转换的结论无外乎以下四条&#xff1a; 如果将子类句柄复制给父类句柄&#xff0c;可以实现父类句柄的向下转换…

翻筋斗觅食策略改进灰狼算法

目录 一、动态扰动因子策略 二、翻筋斗觅食策略 三、改进灰狼算法收敛曲线图 灰狼优化算法(grey wolf optimization,GWO)存在收敛的不合理性等缺陷&#xff0c;目前对GWO算法的收敛性改进方式较少&#xff0c;除此之外&#xff0c;当GWO迭代至后期&#xff0c;所有灰狼个体…

企业版:Select.PDF Library for .NET

HTML 到 PDF API SelectPdf提供了一个REST API&#xff0c;可用于通过我们的专用云服务将html转换为任何语言的pdf。 另存为 PDF 链接 以非常简单的方式将“转换为PDF”功能添加到您的网站或博客。只需添加一个指向您的网页的链接&#xff0c;您就完成了。 适用于 .NET 的 PD…

Redis 通用命令

通用命令介绍 Redis 通用命令是一些 Redis 下可以作用在常用数据结构上的常用命令和一些基础的命令&#xff0c;比如删除键、对键进行改名、判断键是否存在等。简单说&#xff0c;就是 keys 分类的命令&#xff0c;如下图。 上图中圈中的部分&#xff0c;就是所谓的通用的命令…

chatgpt赋能python:Python对于SEO的重要性:浏览网页的技术分析

Python对于SEO的重要性&#xff1a;浏览网页的技术分析 越来越多的网站需要搜索引擎优化&#xff08;SEO&#xff09;&#xff0c;以便他们的网站上的内容能够被更多人浏览与访问。这就要求我们使用一些工具和技术&#xff0c;例如Python&#xff0c;来帮助我们分析网页的技术…