CF 231 E Cactus 题解(仙人掌图上找环)

news2024/9/20 22:44:20

codeforces 提交记录

题意

有一个点仙人掌图(每个点都只属于至多一个简单环),给出 k k k 个询问,问点 x x x 到点 y y y 有多少条简单路径(经过的边不能重复,点可以)。

思路

一看这个样例输出,就感觉有猫腻,肯定和 2 2 2 有关。我们画出一个仙人掌图:图中有三个简单环:1,2,3,4,5;6,7,8;9,10,11,12。如果问点 3 到点 8 的路径,有 4 条:3,4,5,6,8;3,2,1,5,6,8;3,4,5,6,7,8;3,2,1,5,6,7,8。发现这个路径可以分为三段:第一段在第一个环里从 3 走到 5,有两种走法;第二段从 5 走到 6,进入第二个环;第三段在第二个环里从 6 走到 8。那如果是问 3 到 6 呢?是不是没有第三段了?简单路径只是边不能重复,所以从 6 走到 6 有两种走法,绕一圈(6,7,8,6)或者直接停在 6。走过的边的集合不同则路径不同,所以顺时针绕和逆时针绕没有区别。从 5 走到 6 也是 4 种。可以再模拟一下从 3 走到 12,发现是 8 种。得出结论:经过了几个环,就是 2 的几次方,这里的环包括起点和终点所在的环。

实现

由于这张图是一个仙人掌,所以当把每个环都缩成一个点的时候,图就会变成一棵树。我们先用 dfs 找到所有环,在同一个环里的用 b i b_i bi 标记为相同的数值(数值从 n + 1 n+1 n+1 开始,方便区分原来的点和缩点得到的点)。重新建图,对树进行前缀和,用 s u m i sum_i sumi 表示从根节点( b 1 b_1 b1)到 i i i 有多少个环,用 dfs 预处理。要统计 x x x y y y 有几个环,就计算 s u m x + s u m y − 2 ∗ s u m lca ⁡ ( x , y ) + ( lca ⁡ ( x , y ) > n ) sum_x+sum_y-2*sum_{\operatorname{lca}(x,y)}+(\operatorname{lca}(x,y)>n) sumx+sumy2sumlca(x,y)+(lca(x,y)>n)。原理: s u m x + s u m y sum_x+sum_y sumx+sumy 包括了 x x x lca ⁡ ( x , y ) \operatorname{lca}(x,y) lca(x,y) 的环, y y y lca ⁡ ( x , y ) \operatorname{lca}(x,y) lca(x,y) 的环和 lca ⁡ ( x , y ) \operatorname{lca}(x,y) lca(x,y) 到根的环乘上 2。减掉两倍的 lca ⁡ ( x , y ) \operatorname{lca}(x,y) lca(x,y) 到根的环的数量之后还要再加上 lca ⁡ ( x , y ) \operatorname{lca}(x,y) lca(x,y) 的环。 lca ⁡ ( x , y ) \operatorname{lca}(x,y) lca(x,y) 用倍增法就可以啦。

代码

温馨提示:一定要用 scanf,否则会 TLE(本人以为是找环太慢,换了一种写法 qwq)。找环过程建议手动模拟帮助理解。

#include<bits/stdc++.h>
using namespace std;
#define maxlog 18 
#define mod 1000000007 
int n,m,x,y,k,b[100005],sum[200005],tot;
int anc[200005][20],dep[200005];
vector<int> go[100005],e[200005],st;
long long mi[100005];
bool vis[100005];
void dfs(int ps,int fa){
	if(vis[ps]){
		bool flag=0;
		for(int i=0;i<st.size();i++){
			if(st[i]==ps) flag=1,tot++;
			if(flag) b[st[i]]=tot;
		}
		return;
	}
	vis[ps]=1;
	st.push_back(ps);
	for(auto g:go[ps]){
		if(g==fa) continue;
		dfs(g,ps);
	}
	st.pop_back();
}
void pre(int ps,int fa){//sum 和 LCA 的前处理
	sum[ps]=sum[fa]+(ps>n);
	dep[ps]=dep[fa]+1;
	anc[ps][0]=fa;
	for(int i=1;i<maxlog;i++)
		anc[ps][i]=anc[anc[ps][i-1]][i-1];
	for(auto g:e[ps]) if(g!=fa) pre(g,ps);
}
int lca(int x,int y){
	if(x==y) return x;
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=maxlog-1;i>=0;i--)
		if(dep[anc[x][i]]>=dep[y]) x=anc[x][i];
	if(x==y) return x;
	for(int i=maxlog-1;i>=0;i--)
		if(anc[x][i]!=anc[y][i])
			x=anc[x][i],y=anc[y][i];
	return anc[x][0];
}
int main(){
	scanf("%d%d",&n,&m);
	tot=n;mi[0]=1;
	for(int i=1;i<=n;i++){
		mi[i]=mi[i-1]*2%mod;
		b[i]=i;
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&x,&y);
		go[x].push_back(y);
		go[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++)
		for(auto g:go[i])
			if(b[i]!=b[g])
				e[b[i]].push_back(b[g]);
	pre(b[1],0);
	scanf("%d",&k);
	for(int i=1;i<=k;i++){
		scanf("%d%d",&x,&y);
		x=b[x],y=b[y];
		int z=lca(x,y);
		int res=sum[x]+sum[y]-2*sum[z]+(z>n);
		printf("%lld\n",mi[res]);
	}
	return 0;
}

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

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

相关文章

八、垃圾收集器G1ZGC详解

文章目录 G1收集器(-XX:UseG1GC)ZGC收集器(-XX:UseZGC)ZGC目标ZGC内存布局NUMA-awareZGC运作过程颜色指针颜色指针的三大优势读屏障ZGC存在的问题ZGC参数设置 如何选择垃圾收集器安全点与安全区域 G1收集器(-XX:UseG1GC) G1 (Garbage-First)是一款面向服务器的垃圾收集器,主要…

【开源分享】vsomeip 安装、编译、运行步骤笔记

文章目录 1. 摘要2. 安装、编译2.1 开发环境说明2.2 安装依赖2.3 获取代码2.4 编译代码2.5 安装 3. 测试验证参考 1. 摘要 本文主要描述 vsomeip 的安装、编译与运行步骤。下载源码&#xff0c;安装必要依赖&#xff0c;如Boost和CMake。通过CMake配置编译 vsomeip 库&#xf…

fpga系列 HDL:全连接层的浮点数乘法器FM实现

此代码实现了一个简单的浮点数乘法器&#xff0c;处理两个32位的单精度浮点数。它通过将两个浮点数的有效数字部分进行乘法操作&#xff0c;并对结果进行规范化以生成最终的浮点乘积。 主要逻辑与电路 去掉指数对齐部分后的主要逻辑电路图示&#xff1a; 代码 // https://…

海豚调度器DolphinScheduler--单机版DolphinScheduler 入门到实践:从部署到使用

Apache DolphinScheduler 是一个强大的分布式工作流任务调度系统&#xff0c;它以易用性和强大的功能在数据处理领域脱颖而出。本文将从部署到使用&#xff0c;详细介绍 DolphinScheduler 的各个方面&#xff0c;帮助您快速上手并有效利用这一工具。 一、DolphinScheduler 概述…

mac中git操作账号的删除

命令行玩的很溜的可以跳过 找到钥匙串访问 搜github、gitee就行了

k8s的NodeIP、PodIP、ClusterIP、ExternalIP

1.NodeIP K8s集群由Master Node与Worker Node组成。 Node&#xff1a;组成k8s集群的机器&#xff0c;可以是物理机或虚拟机。 Master Node &#xff1a;管理节点也叫控制平面主要负责管理控制方面。 Worker Node&#xff1a;&#xff1a;工作节点用于部署处理业务的工作负载或p…

【计算机网络】IP, 以太网, ARP, DNS

IP, 以太网, ARP, DNS IP协议回顾IP地址报文格式功能介绍地址管理IP地址数量问题初识 NAT 机制通信机制IP数量的解决方案网段划分特殊IP地址 路由选择 以太网协议报文格式源MAC/目的MACMAC地址是什么MAC地址格式MAC的作用 ARPDNS初识DNSDNS主要功能DNS的查询过程 IP协议 回顾I…

协同过滤算法商品推荐系统设计与实现

协同过滤算法商品推荐系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装协同过滤算法商品推荐…

USB数据格式

文章目录 一、域、包、事务的概念1. **域&#xff08;Domain&#xff09;**2. **包&#xff08;Packet&#xff09;****包的类型**&#xff1a; 3. **事务&#xff08;Transaction&#xff09;****总结** 二、USB数据包格式1. **SOP&#xff08;Start of Packet&#xff09;**2…

46.面向对象综合训练-文字版格斗游戏

1.首先创建标准的Javabean类 import java.util.Random;public class 格斗游戏 {private String name;private int blood;public 格斗游戏() {}public 格斗游戏(String name, int blood) {this.name name;this.blood blood;}public String getName() {return name;}public vo…

【C++】vector容器的基本使用

一、vector是什么 vector是STL第一个正式的容器&#xff0c;它的底层其实就是动态数组&#xff0c;插入数据时当容量满了会自动扩容&#xff0c;它和string差不多&#xff0c;不同的之处之一在于vector本身是一个模板&#xff0c;它这个容器中可以存放各种各样的类型的数据&am…

【每日刷题】Day123

【每日刷题】Day123 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 673. 最长递增子序列的个数 - 力扣&#xff08;LeetCode&#xff09; 2. LCR 083. 全排列 - 力扣&…

C语言 | Leetcode C语言题解之题409题最长回文串

题目&#xff1a; 题解&#xff1a; int longestPalindrome(char * s) {int c[128]{0},ret0;for(int i0;i<strlen(s);i){c[s[i]];}for(int i0;i<128;i){retc[i]-c[i]%2;}return ret(ret!strlen(s)); }

【Qt】控件样式案例

例子&#xff1a;设置按钮样式 &#xff08;1&#xff09;设置一个按钮 &#xff08;2&#xff09;右键按钮&#xff0c;选择样式表 &#xff08;3&#xff09;编写全局样式 font-size 设置字体大小&#xff1b; border-radius 设置圆角矩形&#xff1b; background-color 设置…

数据结构-树(基础,分类,遍历)

数据结构-树 1.什么是树&#xff1f; 在计算机科学中&#xff0c;树是一种常用的非线性数据结构&#xff0c;用于表示具有层次关系的数据。与线性数据结构&#xff08;如数组和链表&#xff09;不同&#xff0c;树结构以节点&#xff08;Nodes&#xff09;和边&#xff08;Ed…

日元走强引领外汇市场新动向,全球经济指标波动加剧

日元看涨情绪升温 近期&#xff0c;外汇市场上日元成为焦点&#xff0c;对冲基金纷纷增加对日元上涨的期权投注&#xff0c;预计其将延续本季度强劲表现。上周五&#xff0c;美元兑日元收跌0.65%&#xff0c;盘中触及年内低点&#xff0c;显示出市场对日元未来走势的乐观预期。…

一文了解什么是TTP — 技术、战术与程序

导语&#xff1a;TTP的概念最早来自于军事领域及反恐活动&#xff0c;后面逐渐被应用到网络安全领域&#xff0c;在网络安全中&#xff0c;TTP&#xff08;技术、战术与程序&#xff09;是一个核心概念&#xff0c;它涵盖了攻击者使用的工具、技术和方法&#xff0c;以及他们执…

HTML+CSS - 网页布局之多列布局定位

1. 多列布局 CSS中多列布局处理文本内容&#xff0c;特别适合对于长段落或者大量文本进行自动分栏显示 类似于grid分布&#xff0c;但相较之下更加简洁明了 基本语法 <div class"container"><p>这是一些示例文本&#xff0c;当我们使用 column-count…

SpringBoot Kafka发送消息与接收消息实例

前言 Kafka的基本工作原理 我们将消息的发布&#xff08;publish&#xff09;称作 producer(生产者)&#xff0c;将消息的订阅&#xff08;subscribe&#xff09;表述为 consumer&#xff08;消费者&#xff09;&#xff0c;将中间的存储阵列称作 broker(代理)&#xff0c;这…

酷炫的航模直升机技术详解

1. 分类与级别&#xff08;400级至90级&#xff09; 航模直升机以其独特的飞行魅力和高难度的操作技巧&#xff0c;吸引了众多飞行爱好者。根据模型的尺寸、重量、动力系统及飞行性能&#xff0c;航模直升机大致可分为多个级别&#xff0c;从入门级的400级到专业级的90级及以上…