题解:CF 1200 F Graph Traveler

2024-09-01 18:36
文章标签 graph 1200 题解 cf traveler

本文主要是介绍题解:CF 1200 F Graph Traveler,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Codeforces AC 提交记录

题意

有一张图,可重边可自环。行走规则:初始时有一个值 c c c 和所在的点 x x x,到达一个点就将 c c c 加上点权 k x k_x kx,每次可以走从点 x x x 连出去的第 c % m x c\%m_x c%mx 条边,到达下一个点。有 q q q 个询问,给你 x x x c c c,问在行走过程中有几个点会经过无限次(如果从一个点能走到一个环,问这个环包含的点数;否则是 0 0 0)。

思路

q q q y y y 都太大了,发现 m i m_i mi 很小。 y y y m i m_i mi 取模决定走到哪个点,可以先将 y y y l c m ( 1 , 2 , 3 , . . . , 10 ) lcm(1,2,3,...,10) lcm(1,2,3,...,10) 取模。因为 m i m_i mi 1 1 1 10 10 10 范围内,无论对哪个 m i m_i mi l c m ( 1 , 2 , 3 , . . . , 10 ) lcm(1,2,3,...,10) lcm(1,2,3,...,10) 都是它的倍数,所以不影响 y y y 对每个 m i m_i mi 取模的结果。
当前的值 y y y 对于边是有影响的,遂将 ( x , y ) (x,y) (x,y) 作为一个状态。 l c m ( 1 , 2 , 3 , . . . , 10 ) = 2520 lcm(1,2,3,...,10)=2520 lcm(1,2,3,...,10)=2520,那么状态数最多只有 1000 × 2520 1000\times2520 1000×2520 种,只要用记忆化搜索处理出每种状态的答案,就可以 O ( 1 ) O(1) O(1) 回答问题。

实现

由于 x , y x,y x,y 确定,每种状态有固定的下一个状态: t x = e x , y % m x , t y = y + k t x tx=e_{x,y\%m_x},ty=y+k_{tx} tx=ex,y%mx,ty=y+ktx。我们用 c n t x , y cnt_{x,y} cntx,y 记录答案, f l a g x , y flag_{x,y} flagx,y 记录这个状态在第几次 d f s dfs dfs(在 m a i n main main 函数里被调用第几次)的时候算到了。如果即将到达的状态的 f l a g flag flag 0 0 0,就 d f s ( t x , t y ) dfs(tx,ty) dfs(tx,ty);如果 f l a g flag flag 等于当前的次数,就证明这个环是新找到的,计算环里有几个点并赋值给 c n t x , y cnt_{x,y} cntx,y;如果这个状态在之前的 d f s dfs dfs 中就已经计算过了,证明这个环已经被找到过了,直接 c n t x , y = c n t t x , t y cnt_{x,y}=cnt_{tx,ty} cntx,y=cnttx,ty。最后查询答案的时候要把 x x x 的点权加进去,答案是 c n t x , y + k x cnt_{x,y+k_x} cntx,y+kx
过程中注意 y y y 的取模,由于 y y y 可能是负数, y = ( y % 2520 + 2520 ) % 2520 y=(y\%2520+2520)\%2520 y=(y%2520+2520)%2520。计算环里点的个数时,要用 v i s vis vis 标记一个点是否数过了,因为 s t a c k stack stack 记录的只有 x x x,而状态里是 ( x , y ) (x,y) (x,y),可能重复。
在下图中,原本的路径是黑色的,更新答案的路径是蓝色的:

代码

#include<bits/stdc++.h>
using namespace std;
#define mod 2520
int n,k[1005],m[1005],e[1005][15],q,a,b;
int cnt[1005][2520],st[2520000],pos[1005][2520],flag[1005][2520];
bool vis[1005];
void mo(int& x){ x=(x%mod+mod)%mod; }
void dfs(int x,int y,int id){flag[x][y]=id;st[pos[x][y]]=x;int tx=e[x][y%m[x]];int ty=y+k[tx];mo(ty);if(!flag[tx][ty]){pos[tx][ty]=pos[x][y]+1,dfs(tx,ty,id);cnt[x][y]=cnt[tx][ty];}if(flag[tx][ty]==id){for(int i=pos[tx][ty];i<=pos[x][y];i++)vis[st[i]]=0;for(int i=pos[tx][ty];i<=pos[x][y];i++)if(!vis[st[i]]) vis[st[i]]=1,cnt[x][y]++;}else cnt[x][y]=cnt[tx][ty];
}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&k[i]),mo(k[i]);for(int i=1;i<=n;i++){scanf("%d",&m[i]);for(int j=0;j<m[i];j++) scanf("%d",&e[i][j]);}int l=0;for(int i=1;i<=n;i++)for(int j=0;j<mod;j++)if(flag[i][j]==0) dfs(i,j,++l);scanf("%d",&q);for(int i=1;i<=q;i++){scanf("%d%d",&a,&b);b+=k[a];mo(b);printf("%d\n",cnt[a][b]);}return 0;
}

感谢阅读 Thanks♪(・ω・)ノ。

这篇关于题解:CF 1200 F Graph Traveler的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1127730

相关文章

cf 164 C 费用流

给你n个任务,k个机器,n个任务的起始时间,持续时间,完成任务的获利 每个机器可以完成任何一项任务,但是同一时刻只能完成一项任务,一旦某台机器在完成某项任务时,直到任务结束,这台机器都不能去做其他任务 最后问你当获利最大时,应该安排那些机器工作,即输出方案 具体建图方法: 新建源汇S T‘ 对任务按照起始时间s按升序排序 拆点: u 向 u'连一条边 容量为 1 费用为 -c,

CF 508C

点击打开链接 import java.util.Arrays;import java.util.Scanner;public class Main {public static void main(String [] args){new Solve().run() ;} }class Solve{int bit[] = new int[608] ;int l

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述

LeetCode 第414场周赛个人题解

目录 Q1. 将日期转换为二进制表示 原题链接 思路分析 AC代码 Q2. 范围内整数的最大得分 原题链接 思路分析 AC代码 Q3. 到达数组末尾的最大得分 原题链接 思路分析 AC代码 Q4. 吃掉所有兵需要的最多移动次数 原题链接 思路分析 AC代码 Q1. 将日期转换为二进制表示 原题链接 Q1. 将日期转换为二进制表示 思路分析

图神经网络框架DGL实现Graph Attention Network (GAT)笔记

参考列表: [1]深入理解图注意力机制 [2]DGL官方学习教程一 ——基础操作&消息传递 [3]Cora数据集介绍+python读取 一、DGL实现GAT分类机器学习论文 程序摘自[1],该程序实现了利用图神经网络框架——DGL,实现图注意网络(GAT)。应用demo为对机器学习论文数据集——Cora,对论文所属类别进行分类。(下图摘自[3]) 1. 程序 Ubuntu:18.04

牛客小白月赛100部分题解

比赛地址:牛客小白月赛100_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ A.ACM中的A题 #include<bits/stdc++.h>using namespace std;#define ll long long#define ull = unsigned long longvoid solve() {ll a,b,c;cin>>a>>b>

SIGMOD-24概览Part7: Industry Session (Graph Data Management)

👇BG3: A Cost Effective and I/O Efficient Graph Database in ByteDance 🏛机构:字节 ➡️领域: Information systems → Data management systemsStorage management 📚摘要:介绍了字节新提出的ByteGraph 3.0(BG3)模型,用来处理大规模图结构数据 背景