題意:給定,若,求有多少個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;
}