洛谷P10515 转圈题解

Link

思路

假设目前我们所在的位置是 x x x,那么走一步之后的位置就是 x + x × m = x × ( m + 1 ) x+x\times m=x \times (m+1) x+x×m=x×(m+1),即每走一步我们所在的位置编号就会乘上 ( m + 1 ) (m+1) (m+1)。

于是题意被转化为求最小的正整数 a a a 使得 (m+1)\^a \\equiv 1 \\pmod{n} 。

由于 n n n 是质数,根据费马小定理, ( m + 1 ) n − 1 ≡ 1 ( m o d n ) (m+1)^{n-1} \equiv 1 \pmod{n} (m+1)n−1≡1(modn),于是有 a ∣ n − 1 a|n-1 a∣n−1。我们可以先对 n − 1 n-1 n−1 进行质因数分解,设 n o w now now 初始值为 n − 1 n-1 n−1,我们枚举每一个质因数 x x x,如果 (m+1)\^\\frac{now}{x} \\equiv 1 \\pmod{n} ,我们就令 n o w = n o w x now=\frac{now}{x} now=xnow,即试除,最后 n o w now now 的值就是答案。

这里有一个小技巧,直接分解质因数是时间复杂度 O ( n ) O(\sqrt n) O(n ) 的,但是由于这个题目中 n n n 比较小,我们可以先跑一遍线性筛求出每个数的最小质因子,这样复杂度就是 O ( log ⁡ n ) O(\log n) O(logn) 的了。

代码

时间复杂度 O ( T n log ⁡ 2 n ) O(Tn \log^2 n) O(Tnlog2n)(试除过程中需要用到快速幂)。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int t,n,m,shai[10000005],u[10000005],cnt=0;
bool bj[10000005];
int ksm(int x,int y)
{
	int now=x,op=1;
	for(int i=0;(1<<i)<=y;i++)
	{
		if((1<<i)&y) op=1ll*op*now%n;
		now=1ll*now*now%n;
	}
	return op;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	for(int i=2;i<=1e7;i++)
	{
		if(!bj[i]) u[++cnt]=i,shai[i]=1;
		for(int j=1;j<=cnt&&u[j]*1ll*i<=1e7;j++)
		{
			bj[u[j]*i]=1,shai[u[j]*i]=u[j];
			if(i%u[j]==0) break;
		}
	}
	cin>>t;		
	while(t--)
	{
		cin>>n>>m;
		if(m+1==n)
		{
			cout<<"2\n";
			continue ;
		}
		int now=n-1;
		vector<int> q;
		while(now)
		{
			int y=shai[now];
			if(y==1) break;
			q.push_back(y),now/=y;
		}
		q.push_back(now),now=n-1;
		for(int i=0;i<q.size();i++)
		{
			int u=now/q[i];
			if(ksm(m+1,u)==1) now=u;
		}
		cout<<now<<"\n";
	}
	return 0;
} 
相关推荐
Logic10119 分钟前
C语言/数据结构贪心算法题解:字符串趋同——逐位统计最高频率求最小修改代价
c语言·数据结构·贪心算法·字符串·时间复杂度·频率统计·算法题
the3clipse40 分钟前
H.265熵编码核心:CABAC自适应二进制算术编码详解——如何将语法元素高效压缩为比特流
人工智能·算法·视频编码·h.265·hevc·cabac·cavlc
CQU_JIAKE42 分钟前
10.4【A】
算法
Godspeed Zhao1 小时前
现代智能雷达技术19——算法(5)
算法
(Charon)1 小时前
【C++面试】RAII到底是什么:从资源管理理解C++对象生命周期
c++·算法·面试
无名猿1 小时前
成员初始化列表与初始化顺序陷阱:按声明顺序,不是书写顺序
c++·现代c++·语法基础
Omics Pro1 小时前
之江实验室NAR|虚拟细胞3阶段训练范式
数据库·人工智能·算法·机器学习·自然语言处理
Tisfy1 小时前
LeetCode 0678.有效的括号字符串:O(n)+O(1)一次遍历
算法·leetcode·字符串·题解·贪心·括号匹配
91刘仁德1 小时前
传输层协议深度拆解:端口寻址、UDP 报文与 TCP 可靠性机制全解析
linux·网络·c++·网络协议·tcp/ip·udp·c
小O的算法实验室1 小时前
IEEE TEVC,学习辅助的搜索路径重构进化算法
学习·算法·重构