Codeforces 1295 D. Same GCDs
题意:
给定两个整数\(a,m\leq10^{10}\)。
问有多少个\(0\leq x<m\)有\(gcd(a,m)=gcd(a+x,m)\)。
思路:
把结果写成表达式
\[
\sum_{x=0}^{m-1}[gcd(a,m)=gcd(a+x,m)]
\]
根据gcd的计算过程有:
\[
\sum_{x=0}^{m-1}[gcd(a,m)=gcd((a+x)mod\ m,\ m)]
\]
我们知道\(x\)的取值范围在\([0,m-1]\),其实就是相当于把\(a\)在数轴上向右平移了这么多个单位,取模之后又回到了\([0,m-1]\)的区间。
所以有
\[
\sum_{i=0}^{m-1}[gcd(i,m)=gcd(a,m)]
\]
提取\(gcd(a,m)=d\)。
\[
\sum_{i=0}^{m-1}[gcd(i,m)=g]\\\sum_{0\leq i<m}^{g|i}[gcd(\frac{i}{g},\frac{m}{g})=1]
\]
这个就是\(\varphi(\frac{m}{g})\)。
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll a, m; ll phi(ll x) { ll res = x; for(ll i = 2; i <= x/i; i++) { if(x % i == 0) { res = res/i*(i-1); while(x%i == 0) x /= i; } } if(x > 1) res = res/x*(x-1); return res; } ll gcd(ll a, ll b){ if(b == 0) return a; return gcd(b, a%b); } void solve() { cin >> a >> m; ll k = gcd(a, m); cout << phi(m/k) << endl; } int main() { int T; scanf("%d", &T); while(T--) solve(); }
来源:https://www.cnblogs.com/zxytxdy/p/12262375.html