题目链接:https://codeforces.com/problemset/problem/1848/E
大致题意:
打水漂,某人在海岸线以 f (正整数)的力量扔出石头,会在f,f+(f-1),f+(f-1)+(f-2),........,f+(f-1)+.....+2+1,的位置接触水面;
现在给出坐标x和q次询问,每次询问给出一个y值,将x = x*y;假设石头在x的位置接触水面,问有多少种力量的可能?
答案模M,保证M是一个质数;
解题思路:
如果你对于数字比较敏感的话,那么应该会发现结果和x的奇因子个数有关;
下面贴个官方的证明(某佬翻译过来的):
那么接下来,我们就需要记录x的奇因子的个数,这个可以用map来记录;
当然,这还不够,因为M可以比较小,那么就会出现奇因子个数是M的倍数,导致结果为0,然后那个奇因子下次增加后不是M倍数,但是因为答案上次是0,会导致一直是0,导致出错;
所以,我们需要额外的俩个变量来标记一下,具体可以看代码来理解一下;
时间复杂度:O(nlogn);
代码:
#include<bits/stdc++.h> #define int long long int x, T, mod, ans, res, p;//p和res是额外的变量,与奇因子个数为M的倍数时相关处理有关 std::map<int, int>mp, pre; const int N = 1e6 + 6; int PRIME[N + 6]; std::vector<int> prime; void KSFJZYS()//快速分解质因数 { for (int i = 2; i <= N; ++i) { if (!PRIME[i]) { PRIME[i] = i; prime.push_back(i); } for (auto p : prime) { if (p * i > N)break; PRIME[i * p] = p; if (i % p == 0)break; } } } int QPOW(int a, int b) { int sum = 1; while (b) { if (b & 1)sum = sum * a % mod; b >>= 1; a = a * a % mod; } return sum; } int inv(int a) { return QPOW(a, mod - 2); } void GO(int a) { std::map<int, int> m; while (a != 1)m[PRIME[a]]++, a /= PRIME[a];//本处是分解质因数 for (auto [u, v] : m)//计算过程 { if (u == 2 || v == 0)continue; int I = mp[u] + 1; //std::cout << u << " " << I << " " << v << "\n"; ans = ans * inv(I) % mod; if ((I % mod) == 0)if ((p -= 1) == 0)ans = res; I += v; if ((I % mod) != 0 && p)res = res * I * ((I - v) % mod ? inv(I - v) : 1) % mod; if ((I % mod) == 0)res = res * inv(I - v) % mod, p++; //std::cout << p << " " << res << " " << ans << "s\n"; ans = ans * I % mod; mp[u] = I - 1; if (ans)res = ans; } } signed main() { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); KSFJZYS(); std::cin >> x >> T >> mod; ans = 1; res = 1; for (int i = 2; i * i <= x; ++i) while (x % i == 0)mp[i]++, x /= i; if (x != 1)mp[x]++; for (auto [u, v] : mp)if (u != 2)ans = ans * (v + 1) % mod; res = ans; while (T--) { int a = 0; std::cin >> a; GO(a); std::cout << ans << "\n"; } return 0; }
本题难点在于看出结果和x的奇因子个数有个,然后还要处理M这个模数比较小的问题:)
标签:std,PRIME,Stone,因数分解,885,int,sum,因子,mod From: https://www.cnblogs.com/ACMER-XiCen/p/17659925.html