专栏文章

题解:AT_abc161_f [ABC161F] Division or Subtraction

AT_abc161_f题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@mip57kqz
此快照首次捕获于
2025/12/03 06:21
3 个月前
此快照最后确认于
2025/12/03 06:21
3 个月前
查看原文
建议降黄或橙。

题目分析

非常简单的分讨题,分两种情况。
  1. knk \mid n,即 kknn 的因数,枚举 nn 的因数,将 nn 中所有的 kk 除掉,设 aa 为使 nka\frac{n}{k^a} 为整数的最大值,计 nka=m\frac{n}{k^a} = m,此时 kmk \nmid m,即 kmkk \nmid m - k,所以后续只能进行减法操作,即判断 mmodkm \bmod k 此时是否为 11 即可。
  2. knk \nmid n,同上,k(nk)k \nmid (n - k),所以只能进行减法操作,即 nmodk=1n \bmod k = 1kk 满足条件,即 (n1)modk=0(n - 1) \bmod k = 0。此时求出 n1n - 1 的因数个数即可。
注意:当 k=1k = 1 时,1n1 \mid nnn 会一直除以 11,永远也不会变成 11,注意特判。
最后将两种情况的方案数加起来输出即可。
为何 kk 不会重复呢?
我们会发现第一种情况 knk \mid n,第二种情况 k(n1)k \mid (n - 1),由于 nnn1n - 1 互质,所以 nnn1n - 111 外没有公因数,而 11 我们已经排除掉了,所以两种情况的 kk 不会重复。
时间复杂度约为 O(n)O(\sqrt{n}),计算 mmnka\frac{n}{k^a} 的复杂度可以忽略不计。

AC Code

CPP
#include<bits/stdc++.h>

using namespace std;

#define ll long long

ll n, ans = 0;

int main(){
	cin >> n;
	for(ll i = 1; i * i <= n; i ++){
		if(n % i == 0){
			ll x = n;
			if(i != 1){
				while(x % i == 0)
					x /= i;
				if(x % i == 1) ans ++;
			}
			if(i * i == n) continue;
			x = n;
			if(n / i != 1){
				while(x % (n / i) == 0)
					x /= (n / i);
				if(x % (n / i) == 1) ans ++;
			}
		}
	}
	n --;
	for(ll i = 1; i * i <= n; i ++){
		if(n % i == 0 ){
			if(i != 1) ans ++;
			if(i * i != n) ans ++;
		}
	}
	cout << ans;
	return 0;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...