题意
求解m∑a1=1…m∑an=1n∏i=1aki[gcd(a1,a2…,an)=d]求解m∑a1=1…m∑an=1n∏i=1aki[gcd(a1,a2…,an)=d]
思路
md∑a1=1…md∑an=1n∏i=1akidk[gcd(a1,a2…,an)=1]md∑a1=1…md∑an=1n∏i=1akidk[gcd(a1,a2…,an)=1]
注意有一个dk!注意有一个dk!
dkmd∑a1=1…md∑an=1n∏i=1aki∑ta1…tanμ(t)dkmd∑a1=1…md∑an=1n∏i=1aki∑ta1…tanμ(t)
变换枚举顺序:变换枚举顺序:
dnkmd∑t=1μ(t)mtd∑a1=1…mtd∑an=1n∏i=1akitkdnkmd∑t=1μ(t)mtd∑a1=1…mtd∑an=1n∏i=1akitk
dnkmd∑t=1tnkμ(t)mtd∑a1=1…mtd∑an=1n∏i=1akidnkmd∑t=1tnkμ(t)mtd∑a1=1…mtd∑an=1n∏i=1aki
这里有一个玄学:这里有一个玄学:
mtd∑a1=1…mtd∑an=1n∏i=1aki=(mtd∑i=1ik)nmtd∑a1=1…mtd∑an=1n∏i=1aki=(mtd∑i=1ik)n
因为a可取的值再[1,mtd],而后面那个你可以想成完全平方的概念,更高的数学意义就是每个数都去的所有贡献。因为a可取的值再[1,mtd],而后面那个你可以想成完全平方的概念,更高的数学意义就是每个数都去的所有贡献。
多体会体会,很黑科技。多体会体会,很黑科技。
最后答案为:最后答案为:
dnkmd∑t=1tnkμ(t)(mtd∑i=1ik)ndnkmd∑t=1tnkμ(t)(mtd∑i=1ik)n
注意n要欧拉降幂处理。总复杂度为O(n∗\logn∗\logn+T∗md)注意n要欧拉降幂处理。总复杂度为O(n∗\logn∗\logn+T∗md)
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| ##include "bits/stdc++.h" using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const ll mod = 59964251; const ll phi = 59870352;
bool is\_prime[N]; int prime[N], cnt, mu[N];
void init() { mu[1] = 1; for(int i = 2;i < N; i++) { if(!is\_prime[i]) prime[++cnt] = i, mu[i] = -1; for(int j = 1;j <= cnt && i * prime[j] < N; j++) { is\_prime[i * prime[j]] = 1; if(i % prime[j] == 0) { mu[i * prime[j]] = 0; break; } else mu[i * prime[j]] = -mu[i]; } } }
ll quick\_pow(ll a, ll b) { ll ans = 1; while(b) { if(b & 1) ans = ans * a % mod; a = a * a % mod; b >>= 1; } return ans % mod; }
void solve() { init(); int \_; cin >> \_; while(\_--) { string n; cin >> n; ll p = 0; for(int i = 0;i < n.length(); i++) { p = p * 10 + n[i] - '0'; p = p % phi + phi; } ll m, k, d; cin >> m >> d >> k; vector<ll> f(m / d + 10), F(m / d + 10); for(int i = 1;i <= m / d; i++) { f[i] = (f[i - 1] + quick\_pow(i, k)) % mod; F[i] = quick\_pow(f[i], p); } ll ans = 0; for(int i = 1;i <= m / d; i++) { ans = (ans + quick\_pow(i, p * k) * mu[i] * F[m / (i * d)]) % mod; } ans = ans * quick\_pow(d, p * k) % mod; cout << (ans % mod + mod) % mod << endl; } }
signed main() { solve(); }
|
本文作者:jujimeizuo
本文地址: https://blog.jujimeizuo.cn/2021/04/11/2019-icpc-yinchuan-easy-problem/
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0 协议。转载请注明出处!