【模拟赛】【数论】2021.8.12.D

题目描述

给出n,求所有x,使得x小于n,且 x 2   %   n   =   1 x ^ 2\ \%\ n\ =\ 1 x2 % n = 1
将所有x从小到大输出

思路

x 2   %   n   =   1 x ^ 2\ \%\ n\ =\ 1 x2 % n = 1
( x 2   −   1 )   %   n   =   0 (x^2\ -\ 1)\ \%\ n\ =\ 0 (x2  1) % n = 0
x 2   −   1 = k n x^2\ -\ 1 = kn x2  1=kn
( x   −   1 ) ( x   +   1 )   =   k n (x\ -\ 1)(x\ +\ 1)\ =\ kn (x  1)(x + 1) = kn
然后设
( x   +   1 )   =   k 1 ∗ n 1 (x\ +\ 1)\ =\ k_1 * n_1 (x + 1) = k1n1
( x   −   1 )   =   k 2 ∗ n 2 (x\ -\ 1)\ =\ k_2 * n_2 (x  1) = k2n2
k 1 ∗ k 2 = k k_1 * k_2 = k k1k2=k
n 1 ∗ n 2 = n n_1 * n_2 = n n1n2=n
我们枚举 n 1 n_1 n1并记为 a a a
那么
n 2   =   n   /   a n_2\ =\ n\ /\ a n2 = n / a
( x   +   1 )   =   k 1   ∗   a (x\ +\ 1)\ =\ k_1\ *\ a (x + 1) = k1  a
我们再枚举 k 1 k_1 k1,记作 b b b
( x   +   1 )   =   a   ∗   b (x\ +\ 1)\ =\ a\ *\ b (x + 1) = a  b
x   =   a   ∗   b   −   1 x\ =\ a\ *\ b\ -\ 1 x = a  b  1
将此式代入 ( x   −   1 )   =   k 2 ∗ n 2 (x\ -\ 1)\ =\ k_2 * n_2 (x  1) = k2n2
( a   ∗   b   −   1 )   =   k 2   ∗   ( n   /   a ) (a\ *\ b\ -\ 1)\ =\ k_2\ *\ (n\ /\ a) (a  b  1) = k2  (n / a)
( a   ∗   b   −   2 ) (a\ *\ b\ -\ 2) (a  b  2) ( n   /   a ) (n\ /\ a) (n / a)的倍数
x   =   a   ∗   b   −   1 x\ =\ a\ *\ b\ -\ 1 x = a  b  1为一组解
其余参考大爷博客

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;

ll Ans[5000250];
ll n, m, t;

void init(ll n1)
{
	for(ll k1 = 0; k1 <= n / n1; ++k1)
	{
		m = n1 * k1 - 2;//处理(x-1)和(x+1)
		if(m % (n / n1) == 0)Ans[++t] = n1 * k1 - 1;
		m = n1 * k1 + 2;
		if(m % (n / n1) == 0)Ans[++t] = n1 * k1 + 1;
	}
}

int main()
{
	scanf("%lld", &n);
	if(n == 1){printf("None\n"); return 0;}
	for(int i = 1; i <= (ll)sqrt(n); ++i)
		if(!(n % i))init(n / i);
	sort(Ans + 1, Ans + t + 1);
	t = 0;
	while(Ans[++t] <= 0);t--;
	while(Ans[++t] && Ans[t] <= n)if(Ans[t] != Ans[t - 1])printf("%lld\n", Ans[t]);
	return 0;
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值