bzoj5213: [Zjoi2018]迷宫
好题!话说省选的都开始构造了吗
由于有K的倍数的限制所以不妨取模,先建K个点表示0~K-1这些数,第i个点向[i*m,i*m+m]建边。不难发现这是合法的但不一定是最优的
考虑合并等价的点,首先从直观上考虑,当两个点能够转移到的点相同时,它们一定可以合并,但是能够合并的点远远不止这些
考虑一般化,对于两个节点x,y,假设x*m^q=y*m^q (mod K) 那么只要在q步中x和y没有到达0节点的方案,那么x和y就可以合并
具体的,首先0一定不能被删掉,现在考虑q=1时,1~K-1中等价点
把所有数乘m,只有gcd(m,K)的倍数才能表示出来,对于变成同一个数的点就可以去重了(不过并不需要具体实行这一步骤)
然后,对于能够表示出的能够到达0节点的点,无论如何都没有办法合并,把其中还存在的点计入答案(q=1都存在,但是q递增后就变化了)
让q++,把乘完m得出的每个不同的数拿出来继续进行上述操作,每一轮相当于把在第q轮可以到达0节点且在之前的轮中没有被删的节点计入答案,再把恰好在第q轮等价的点去重(感觉用unique表达更贴切)
现在我们目标是快速模拟这个过程,令f(l,K),表示现在要解决的数值域为[1,l],模数为K,考虑如何递归求解
若l<=K/d,没有溢出不会相交,直接返回l即可
仅考虑q=1的情况,在后期继续递归的时候再考虑满足条件。对于以前可以到达0的数为[(K-l),K],那么此时已经可以到达0的数为[K-m*(K-l),K],在这个值域的数的个数为m*(K-l)/gcd(m,K),计入答案(这里可能有点玄学,可以先看下面再回来看)
为了保证值域连续,当把数都变成gcd(m,K)的倍数后,令所有数都除以gcd(m,K)变为连续,此时上界为(K-m*(K-l))/gcd(m,K)(注意m*(K-l)是可以到达0的数的个数,是要保留的部分不参与递归了。用总数减去保留的数量剩下的再变成压缩同余系),相应的同余系大小K也应该变成K/gcd(m,K)
最终继续递归求f((K-m*(K-l))/gcd(m,K),K/gcd(m,K)),注意会有l>K的情况,此时会取遍K/gcd(m,K)直接返回即可
有一个疑问是对于值的改变是否m也应该随之改变?
ccosi(远行客)的说法:(感谢大佬的解答)
你是不是觉得应该乘上m/d?
事实上(k-l)这里已经/d了,所以是直接乘m,下一层的k-m(k-l)就是上一层的k/d-m((k-l)/d)
我的理解是对于每个数我们是乘上而不是加上m,那么域的变化是不影响乘法的
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
LL gcd(LL a,LL b){return (a==)?b:gcd(b%a,a);} LL m;
LL solve(LL l,LL K)
{
LL d=gcd(m,K);
if(l<=K/d)return l;
if(K<=(double)m*(K-l))return K/d;
else return m/d*(K-l)+solve((K-m*(K-l))/d,K/d);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
LL K;
scanf("%lld%lld",&m,&K);
printf("%lld\n",solve(K-,K)+);
} return ;
}
bzoj5213: [Zjoi2018]迷宫的更多相关文章
- 【BZOJ5213】[ZJOI2018]迷宫(神仙题)
[BZOJ5213][ZJOI2018]迷宫(神仙题) 题面 BZOJ 洛谷 题解 首先可以很容易的得到一个\(K\)个点的答案. 构建\(K\)个点分别表示\(mod\ K\)的余数.那么点\(i\ ...
- yyb博客的几道神仙题
该比赛链接 T5 题意: 给你一个\(n\times n\)的网格,开始有\(m\)个被涂成黑色的格子,如果存在三个格子\((x,y)\),\((y,z)\),\((z,x)\)满足\((x,y)\) ...
- yyb省选前的一些计划
突然意识到有一些题目的计划,才可以减少大量查水表或者找题目的时间. 所以我决定这样子处理. 按照这个链接慢慢做. 当然不可能只做省选题了. 需要适时候夹杂一些其他的题目. 比如\(agc/arc/cf ...
- UOJ#375. 【ZJOI2018】迷宫
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ375.html 题解 首先,我们可以建出一个 k 个点的自动机,第 i 个点表示当前数对 k 取模为 i- ...
- C语言动态走迷宫
曾经用C语言做过的动态走迷宫程序,先分享代码如下: 代码如下: //头文件 #include<stdio.h> #include<windows.h>//Sleep(500)函 ...
- POJ 2251 Dungeon Master(3D迷宫 bfs)
传送门 Dungeon Master Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 28416 Accepted: 11 ...
- BFS_Maze_求解迷宫最短路径
/* 10 10 #.######.# ......#..# .#.##.##.# .#........ ##.##.#### ....#....# .#######.# ....#..... .## ...
- 【刷题笔记】I'm stuck! (迷宫)-----java方案
题目描述 : 给定一个R行C列的地图,地图的每一个方格可能是'#', '+', '-', '|', '.', 'S', 'T'七个字符中的一个,分别表示如下意思: '#': 任何时候玩家都不能移动到此 ...
- canvas实例 ---- 制作简易迷宫(一)
这个系列分为两部分,第一部分为迷宫的生成及操作,第二部分为自动寻路算法. 我们先看效果: See the Pen QGKBjm by fanyipin (@fanyipin) on CodePen. ...
随机推荐
- 【MVC2】发布到IIS7.5上后Session为null
MVC2代码「Session.IsNewSession」在VS中可以正常执行,发布到IIS7.5上之后Session为null导致出错. if (Session.IsNewSession) { ... ...
- shell程序
例一:helloworld #!/bin/sh -x message="hello" read name echo "$message ,$name" 例二:选 ...
- MySQL具体解释(14)----------事务处理
前言:前一篇文章关于事务处理的博文没有写清楚,读起来非常晦涩.非常难理解,所以有整理了一些资料,帮助理解.见谅! 关于MySQL事务处理学习记 START TRANSACTION COMMIT ROL ...
- apue学习笔记(第十七章 高级进程间通信)
本章介绍一种高级IPC---UNIX域套接字机制,并说明它的应用方法 UNIX域套接字 UNIX域套接字用于在同一台计算机上运行的进程(无关进程)之间的(全双工)通信.相比于因特网套接字,UNIX域套 ...
- C#各种导入Excel文件的数据的方法总结
在导入前都需要将上传的文件保存到服务器,所以避免重复的写这些代码,先贴出上传文件并保存到服务器指定路径的代码 protected void btnImport_Click(object sender, ...
- 26最小公倍数 lowest common multiple
题目描述 正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数. 输入描述:输入两个正整数A和B. 输出描述:输出A和B的最小公倍数. 输入例子 ...
- 基于jenkins,tekton等工具打造kubernetes devops平台
本贴为目录贴,将不断更新 目录 1.Docker在centos下安装以及常见错误解决 2.使用kubernetes 官网工具kubeadm部署kubernetes(使用阿里云镜像) 3.无法访问gcr ...
- apt-mirror 校验错误文件处理
apt-mirror是一个用来将Debian或Ubuntu的软件源镜像到本地的工具,这个工具工作得非常好,不过有的时候由于网络问题,会有一些文件的校验是失败的,但apt-mirror并不能发现,等到最 ...
- YARN/MRv2 中基本术语介绍
YARN/MRv2是下一代MapReduce框架(见Hadoop-0.23.0),该框架完全不同于当前的MapReduce框架,它在扩展性,容错性和通用性等方面更出色,据统计,Yarn有超过15000 ...
- 时间控件(DateTime Picker)
中文:http://www.bootcss.com/p/bootstrap-datetimepicker/index.htm http://www.malot.fr/bootstrap-datetim ...