# [CF1499D]The Number of Pairs 数学

### D. The Number of Pairs

#### 题意

$T$组数据
$T <= 10^4$, $c, d, x <= 10^7$

#### 题解

$cl - dg = x$

$\therefore \frac{cab}{g} - dg = x$

$cktg - dg = x$

$g = \frac{x}{ckt - d}$

$\because i = ckt - d$

$\therefore kt = \frac{i + d}{c}$

$\frac{i + d}{c} = \prod_{j<=m}{p_j^{f_j}}$, $m$$\frac{i + d}{c}$的质因数种数，$f_j$表示$p_j$这个质因数有$f_j$

$\sum{2^{m(\frac{i + d}{c})}}$大概不会超过$\frac{i + d}{c} \cdot i$个，也就差不多是$10^{14}$这个级别，用longlong应该就够了

$m(i)$可以欧拉筛预处理一下搞搞，2的幂也可以预处理一下

---update in 21.5.7---

#include<bits/stdc++.h>
using namespace std;
#define R register int
#define LL long long
#define AC 14000000
#define ac 20000000 + 3

int T, tot;
LL c, d, x, ans;
int pri[AC], m[ac];
bool z[ac];
LL two[80];

{
int x = 0; char c = getchar(); bool z = 0;
while((c > '9' || c < '0') && c != '-') c = getchar();
if(c == '-') z = 1, c = getchar();
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return z ? -x : x;
}

void get_prime()
{
z[1] = 1;
for(R i = 2; i <= 20000000; i ++)
{
if(!z[i]) pri[++ tot] = i, m[i] = 1;//不要忽略i本身是质数时m(i) = 1
for(R j = 1; j <= tot && i * pri[j] <= 20000000; j ++)
{
z[i * pri[j]] = 1, m[i * pri[j]] = m[i] + 1;
if(!(i % pri[j]))
{
m[i * pri[j]] --;//如果i * pri[j]剩下那个因子i里也有pri[j]这个因子，那就不用重复统计了
break;
}
}
}
//	printf("%d", tot);
}

void get_two()//才几十不用快速幂
{
two[0] = 1;
for(R i = 1; i <= 63; i ++) two[i] = two[i - 1] << 1;
}

void work()
{
while(T --)
{
int t = sqrt(x), now;
ans = 0;
for(R i = 1; i <= t; i ++)
{
if(x % i) continue;//首先要是x的因子
if(!((i + d) % c))// continue; 这里不能直接continue,因为后面那个可能是可以算的阿
{
now = (i + d) / c;
ans += two[m[now]];//注意now的范围可以很大
}
if((x / i + d) % c || i * i == x) continue;
now = (x / i + d) / c;
ans += two[m[now]];
}
printf("%lld\n", ans);
}
}

int main()
{
freopen("in.in", "r", stdin);
get_prime();
get_two();//预处理2的阶乘
work();
return 0;
}

posted @ 2021-05-03 19:15  ww3113306  阅读(64)  评论(0编辑  收藏  举报