積性函式 hdu5528 Count a * b
阿新 • • 發佈:2019-01-05
積性函式太有趣了!
做這個題之前,我們需要掌握一些基本知識。
1.若f(x)為積性函式,那麼滿足f(xy)=f(x)f(y)
2.若f(x)為積性函式,g(x)=∑d|xf(d) ,那麼g(x)也為積性函式
3.學會如何線性處理積性函式。
4.對於積性函式,目標就是學會如何求f(pq) ,p為質數
回到這個題,我們先考慮求f函式
我們考慮a b的所有組合,一共
考慮f函式的反面,即
若 (m,ab)=m
滿足
在上面情況滿足下且滿足
得到
能發現前者和後者都是積性函式,拆成2部分記為f1,f2
然後g函式也拆成2部分,記為g1,g2
因為我們知道g1和g2是積性的,所以很容易打表就能找到規律(QAQ太弱了,推不出來,只能打表)
得到
這題就做完啦
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <memory>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cassert>
#include <climits>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define fuck(x) std::cout << "[" << x << "]";
#define FIN freopen("input.txt", "r", stdin);
#define FOUT freopen("output.txt", "w+", stdout);
typedef long long ll;
typedef long double ldb;
typedef std::pair<ll, int> pli;
typedef std::pair<int, int> pii;
typedef unsigned long long ull;
typedef std::pair<double, double> pdd;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int mod = 1e9 + 7;
const int MX = 4e4 + 5;
int prime[MX], psz;
bool not_prime[MX];
void prepare() {
not_prime[1] = true;
for(int i = 2; i < MX; i++) {
if(!not_prime[i]) {
prime[++psz] = i;
}
for(int j = 1; j <= psz && (ll)i * prime[j] < MX; j++) {
int x = i * prime[j];
not_prime[x] = true;
if(i % prime[j] == 0) break;
}
}
}
ull solve(int n) {
ull g1 = 1, g2 = 1;
for(int i = 1; i <= psz && (ll)prime[i]*prime[i] <= n; i++) {
if(n % prime[i] == 0) {
int p = prime[i], q = 0;
while(n % prime[i] == 0) {
q++; n /= prime[i];
}
ull f1 = 1, f2 = q + 1;
for(int j = 1; j <= q; j++) {
f1 = f1 * p * p + 1;
f2 = f2 * p;
}
g1 *= f1; g2 *= f2;
}
}
if(n != 1) {
int p = n;
g1 *= (ull)p * p + 1;
g2 *= 2 * p;
}
return g1 - g2;
}
int main() {
// FIN;
prepare();
int T; scanf("%d", &T);
while(T--) {
int n; scanf("%d", &n);
printf("%llu\n", solve(n));
}
return 0;
}