专栏文章
题解:AT_abc222_g [ABC222G] 222
AT_abc222_g题解参与者 10已保存评论 13
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 13 条
- 当前快照
- 1 份
- 快照标识符
- @mipcor9c
- 此快照首次捕获于
- 2025/12/03 09:50 3 个月前
- 此快照最后确认于
- 2025/12/03 09:50 3 个月前
AT_abc222_g [ABC222G] 222 题解分析
思路
题意转化
等价于求最小的 使得:
引理部分
引理 :若 ,那么 。
引理 :若 ,那么 。
变换
不难用两个引理转换题意为:
其中 是最小满足条件的数,以及:
注意到欧拉定理:
所以:
我们假设 ,其中 为整数。
则:
推导得:
由于:
故:
由于 是最小满足条件的,所以:
其中 为整数。
- 若 ,则 ,得到 。
- 若 ,则 ,得到 。
综上所述:
故我们可以暴力枚举 的因子求出最小满足条件的 即可,时间复杂度为 。
引理推导
引理 推导:
设 ,则设 。
有:
设 为正整数,有:
得到:
所以:
由于:
所以又有:
引理 推导:
跟上述差不多。
首先设 为正整数,可以得到:
然后就有:
所以:
代码
时间复杂度 ,代码如下:
CPP#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stdlib.h>
#include <cstring>
#include <vector>
#define int long long
#define N 100000001
#define M 5761457
using namespace std;
int T;
//bool vis[N];
//int prime[N],phi[N],cnt;
int qpow(int a,int b,int mod) {
int res = 1;
while(b) {
if (b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
//void init(int n) {
// phi[1] = 1;
// for (int i = 2;i <= n;i ++) {
// if (!vis[i]) prime[++cnt] = i,phi[i] = i - 1;
// for (int j = 1;j <= cnt && prime[j] * i <= n;j ++) {
// vis[prime[j] * i] = 1;
// if (i % prime[j] == 0) {
// phi[i * prime[j]] = prime[j] * phi[i];
// break;
// }
// phi[i * prime[j]] = phi[prime[j]] * phi[i];
// }
// }
//// cout << cnt << endl;
//// for (int i = 1;i <= cnt;i ++) cout << prime[i] << ' ';
//}
int get_euler(int x) {
int res = x;
for (int i = 2;i * i <= x;i ++)
if (x % i == 0){
while(x % i == 0) x /= i;
res = res / i * (i - 1);
}
if (x > 1) res = res / x * (x - 1);
return res;
}
signed main(){
//int T;
cin >> T;
for (;T--;) {
int x;
scanf("%lld",&x);
int mod = ((x & 1) ? x * 9 : x / 2 * 9),phi = get_euler(mod),res = phi + 1;
for (int i = 1;i * i <= phi;i ++)
if (phi % i == 0) {
// cout << i << ' ' << qpow(10,i,mod) << endl;
if (qpow(10,i,mod) == 1) res = min(res,i);
if (qpow(10,phi / i,mod) == 1) res = min(res,phi / i);
}
if (res == phi + 1) puts("-1");
else printf("%lld\n",res);
}
return 0;
}
感谢管理员的审核,最后一次更改了一些细节。
相关推荐
评论
共 13 条评论,欢迎与作者交流。
正在加载评论...