Educational Codeforces Round 106 (Rated for Div. 2)D. The Number of Pairs(推式子)

Posted 吃花椒的妙酱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 106 (Rated for Div. 2)D. The Number of Pairs(推式子)相关的知识,希望对你有一定的参考价值。

传送门

题目大意:给c,d,x,求满足c * lcm(a,b) - d * gcd (a,b) = x的ab的对数

思路:推式子

设lcm(a,b) = k * gcd(a,b)

c * lcm(a,b) - d * gcd (a,b) 

= (ck - d) * gcd(a,b) = x

其中ck-d和gcd是x的因子

设ck - d = z

则  k = (z+d)/c,其中z+d被c整除

现在k和gcd都已知了,看lcm(a,b) = k*gcd(a,b)是否满足即可

两边同除gcd(a,b),得lcm(a',b') = k,其中 gcd(a',b')=1,即a'b'互质

现在k已知,求a'b'互质的对数,显然k的某个质因子要么全在a'中要么全在b'中,k若有cnt个质因子,则a'b'对数为 2^cnt 

注意:分解k的时候,每次除以k的最小质因子是最快的分解算法(用了暴力从2筛到根号k的方法tle掉了),需要在线性筛的时候预处理出每个数的最小质因子,由于是最坏情况是2e7的范围,是可以接受的

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
using namespace std;
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define pb push_back
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define int long long
#define inf 0x7f7f7f7f7f7f7f7f
#define pii pair<int ,int >
#define fi first
#define se second
#define endl "\\n"
typedef long long ll;
const int N=2e7+10;
int n,m,k,x,d,c;
int p[N>>1],v[N];
int cnt=0;
void shai(int n)
{
    _for(i,2,n)
    {
        if( !v[i] )
        {
            p[++cnt] = i;
        }
        _for(j,1,cnt)
        {
            if( i*p[j] > n ) break;
            v[i*p[j]]=p[j];//最小质因子
            if( i%p[j] == 0 ) break;
        }
    }
}
vector <int > vv;
int cal(int x)
{
    int num=0;
    while( x>1 && v[x] )
    {
        int y = v[x];num++;
        while( x%y==0 && x )
        {
            x /= y;
        }
    }
    if( x>1 && !v[x] ) num++;
    return 1<<(num);
}
void solve()
{
    _for(i,1,sqrt(x))
    {
        if( x%i || (d+i)%c ) ;
        else vv.pb((d+i)/c);

        if( x%i ) continue;
        if( x/i == i ) continue;
        int t = x/i;
        if(  (d+t)%c ) continue;
        vv.pb((d+t)/c);
    }
    int ans=0;
    for(int u:vv) ans += cal(u);
    vv.clear();
    cout<<ans<<endl;
}
signed main()
{
//    freopen("data.txt","r",stdin);
    IOS;
    shai(2e7);
    int T;cin>>T;
    while( T-- )
    {
        cin>>c>>d>>x;
        solve();
    }
}

以上是关于Educational Codeforces Round 106 (Rated for Div. 2)D. The Number of Pairs(推式子)的主要内容,如果未能解决你的问题,请参考以下文章

Educational Codeforces Round 7 A

Educational Codeforces Round 7

Educational Codeforces Round 90

Educational Codeforces Round 33

Codeforces Educational Codeforces Round 54 题解

Educational Codeforces Round 27