传送门
题意:给定,若,求有多少个x满足
题解:如果满足gcd相同则x必须为gcd(a,m)的倍数,设,则若,有多个w满足。因为d是最大公因数所以。到这里(凭借丰富的骗分经验?)就可以直接猜一波答案是phi(v)了。所以求个gcd再求个欧拉函数就完事儿。一开始欧拉函数没写好还T了一发......这次真的是自己把答案猜对的(*—*)
下面证明一下答案:
相当于要证正整数序列上每个长度为v的周期内与v互质的数的个数相等并且它们的分布是和第一个周期[1, v]是相同的。即证,然后充分性和必要性都反证一下就好了。
为什么证明了与v互质的数的分布的周期性就好?因为有了周期性后,可以把询问的区间进行平移。最后和就可以转化为和。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; ll a,m; inline ll read() { ll x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); return x*f; } inline ll gcd(ll a,ll b) { return !b?a:gcd(b,a%b); } inline ll phi(ll x) { ll ret=1; for (register ll i=2;i*i<=x;++i) if (x%i==0) { ll cur=1; while (x%i==0) { cur*=i; x/=i; } ret*=(i-1)*cur/i; } if (x>1) ret*=x-1; return ret; } int main() { int kase=read(); while (kase--) { a=read(),m=read(); ll v=m/gcd(a,m); printf("%lld\n",phi(v)); } return 0; }