小花梨的函数
题目: https://acm.ecnu.edu.cn/contest/173/statements/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define LL long long #define ULL unsigned long long #define rep(i,j,k) for(int i=j;i<=k;i++) #define dep(i,j,k) for(int i=k;i>=j;i--) #define INF 0x3f3f3f3f #define mem(i,j) memset(i,j,sizeof(i)) #define make(i,j) make_pair(i,j) #define pb push_back using namespace std; const int N = 2e7 + 10; int f[N]; bool vis[N]; int pre[N]; int mu[N]; void init(int n) { int tot = 0; vis[1] = mu[1] = 1; rep(i, 2, n) { if(!vis[i]) pre[++tot] = i,mu[i] = -1; rep(j, 1, tot) { if(i * pre[j] > n) break; vis[i * pre[j]] = 1; if(i % pre[j]) mu[i * pre[j]] = -mu[i]; if(i % pre[j] == 0) break; } } rep(i, 1, n) mu[i] += mu[i-1]; } LL cal(int n,int m) { LL ans=0; for(LL l = 1, r; l <= n; l = r + 1) { r = min(n / (n / l),m / (m / l)); ans += (mu[r] - mu[l - 1]) * (n / l) * (m / l); } return ans; } int main() { int n, m, a, p; scanf("%d %d %d %d",&n, &m, &a, &p); f[1] = f[2] = 1; int cnt; rep(i, 3, N-1) { f[i] =(f[i-1] + f[i-2]) % p; if(f[i] == 1 && f[i-1] == 1) { cnt = i - 2; break; } } if(n > m) swap(n, m); init(n); LL ans = 0; LL tmp = 1; rep(i, 1, n) { tmp = tmp * a % cnt; LL tot = cal(n / i, m / i) % p;///求gcd的 次数 ans = (ans + tot * f[(tmp + cnt - 1) % cnt] % p) % p; ///求和; } printf("%lld\n", ans); return 0; }
一步一步,永不停息