https://codeforces.com/contest/1499/problem/D
Reference solution:
https://blog.csdn.net/ghu99999/article/details/115006433
Ideas:
First, the sufficient and necessary conditions for the solution of the Pei Shu theorem ax+by=c can be obtained
For the equation lcm(a,b)*c+gcd(a,b)*(-d)=x, x must be a multiple of gcd(gcd(a,b),lcm(a,b))
Consider gcd(a,b) as the prime factor of a, b and take min, and lcm(a,b) as the prime factor of a, b and take max, you can find that the answer is still gcd(a,b)
Therefore, we can know that gcd(a,b) is a divisor of x. At this time, sqrt can enumerate the value of gcd(a,b). Since c,d, is known, O1 can get lcm(a, b);
At this time, the problem becomes how many pairs of ab that gcd(a,b) and lcm(a,b) are satisfied are already known.
Here is the conclusion part and the comparative thinking part.
Reference: https://blog.csdn.net/qq_36394234/article/details/114994557
At this point, 2^nO1 can be used to calculate the answer, but it should be noted that the divisibility of the formula must be satisfied. That is, lcm%c==0, and lcm must be a multiple of gcd.
So start the preprocessing part. Normally, we finish the log run by Euler Sieve, n+nlogn. However, I opened LL, which caused tle1 to be confused for a long time. Finally, 1996ms stuck.
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
#define LL int
using namespace std;
const int maxn=2e7+5000;
inline LL read(){LL x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL primes[1270610],m=0;
LL v[maxn];//[]存每个数的最小质因子
LL num[maxn];
void getprimes(LL n){
for(int i=2;i<=n;i++){
if(v[i]==0) {v[i]=i;primes[++m]=i;}
for(LL j=1;j<=m;j++){
if(primes[j]>v[i]||primes[j]>n/i) break;
v[i*primes[j]]=primes[j];
}
}
for(int i=2;i<=n;i++){
LL k=i;LL cnt=0;
while(k>1){
LL temp=v[k];
cnt++;
while(k%temp==0){
k/=temp;
}
}
if(k>1) cnt++;
num[i]=cnt;
}
}
LL add(LL c,LL d,LL x,LL gcd){
long long int lcm=x+1ll*d*gcd;
long long int res=0;
if(lcm%c==0){
lcm/=c;
if(lcm%gcd==0){
res+=(1ll<<num[lcm/gcd]);
}
}
return res;
}
void solve(LL c,LL d,LL x){
long long int ans=0;
for(LL i=1;i*i<=x;i++){
if(x%i==0){
ans+=add(c,d,x,i);
if(i*i!=x) ans+=add(c,d,x,x/i);
}
}
printf("%lld\n",ans);
}
int main(void)
{
getprimes(20000010);
int T;scanf("%d",&T);
while(T--){
LL c,d,x;c=read();d=read();x=read();
solve(c,d,x);
}
return 0;
}
This is too dangerous. Seeing that everyone else is Essie, isn’t Euler working? It can still be screened out on
Let's look at Euler Sieve again, num[i] is the number of prime factors of i. When i%primes[j]!=0, the update of num[i*primes[j]] comes from a part of num[i] and primes[j].
When i%primes[j[==0, primes[j] itself is contained in num[i]. Therefore num[i*primes[j]=num[i]
Then On ran. 1200ms.
It's still not fast. Is it 1005ms to sieve the cin..
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
#define LL int
using namespace std;
const int maxn=2e7+5000;
inline LL read(){LL x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL primes[1270610],m=0;
LL v[maxn];//[]存每个数的最小质因子
LL num[maxn];
void getprimes(LL n){
for(int i=2;i<=n;i++){
if(v[i]==0) {v[i]=i;primes[++m]=i;num[i]=1;}
for(LL j=1;j<=m&&primes[j]<=n/i;j++){
v[i*primes[j]]=primes[j];
if(i%primes[j]==0){
num[i*primes[j]]=num[i];
break;
}
num[i*primes[j]]=(1+num[i]);
}
}
}
LL add(LL c,LL d,LL x,LL gcd){
long long int lcm=x+1ll*d*gcd;
long long int res=0;
if(lcm%c==0){
lcm/=c;
if(lcm%gcd==0){
res+=(1ll<<num[lcm/gcd]);
}
}
return res;
}
void solve(LL c,LL d,LL x){
long long int ans=0;
for(LL i=1;i*i<=x;i++){
if(x%i==0){
ans+=add(c,d,x,i);
if(i*i!=x) ans+=add(c,d,x,x/i);
}
}
printf("%lld\n",ans);
}
int main(void)
{
getprimes(20000010);
int T;scanf("%d",&T);
while(T--){
LL c,d,x;c=read();d=read();x=read();
solve(c,d,x);
}
return 0;
}