【杜教筛/min25筛】计蒜客 Easy Math

S o u r c e : Source: Source:ACM-ICPC 2018 徐州赛区网络预赛
I d e a : Idea: Idea:
f ( n , m ) = ∑ i = 1 m μ ( i ∗ n ) = μ ( n ) ∗ ∑ i = 1 m μ ( i ) [ g c d ( i , n ) = 1 ] f(n,m)=\sum_{i=1}^{m}\mu(i*n)=\mu(n)*\sum_{i=1}^{m}\mu(i)[gcd(i,n)=1] f(n,m)=i=1mμ(in)=μ(n)i=1mμ(i)[gcd(i,n)=1] = μ ( n ) ∗ ∑ d ∣ n μ ( d ) ∑ i = 1 ⌊ m d ⌋ μ ( i ∗ d ) = μ ( n ) ∗ ∑ d ∣ n μ ( d ) f ( d , ⌊ m d ⌋ ) ( 莫 比 乌 斯 反 演 ) =\mu(n)*\sum_{d|n}\mu(d)\sum_{i=1}^{\lfloor \frac{m}{d} \rfloor} \mu(i*d) = \mu(n)*\sum_{d|n}\mu(d)f(d, \lfloor \frac{m}{d} \rfloor) (莫比乌斯反演) =μ(n)dnμ(d)i=1dmμ(id)=μ(n)dnμ(d)f(d,dm)()
f ( 1 , m ) = ∑ i = 1 m μ ( i ) , f ( n , 1 ) = μ ( n ) ( 杜 教 筛 ) f(1, m) = \sum_{i=1}^m \mu(i), f(n, 1) = \mu(n) (杜教筛) f(1,m)=i=1mμ(i),f(n,1)=μ(n)()
也可以考虑min_25筛,素数部分减去n的质因子,合数部分减去这些质因子的倍数。

C o d e : Code: Code:

//杜教筛
#include
using namespace std;
#define Toocold
#define I inline
#define lc o<<1
#define rc o<<1|1
#define fi first
#define se second
#define pb push_back
#define ALL(X) (X).begin(), (X).end()
#define bcnt(X) __builtin_popcountll(X)
#define CLR(A, X) memset(A, X, sizeof(A))
using DB = double;
using LL = long long;
using PII = pair;
#ifdef Toocold
#define dbg(args...)\
do { cout << "DEBUG: " << #args << " -> "; err(args); } while(0)
#else
#define dbg(...)
#endif // Toocold
void err() { puts(""); }
template class T, typename t, typename... Args>
void err(T a, Args... args) { for(auto x:a) cout << x << ' '; err(args...); }
template
void err(T a, Args... args) { cout << a << ' '; err(args...); }
/*-----------------------------------------------------------------------------*/

const int N = 1e6+10;

int p[N], pnt;
bool isn[N], vis[N];
LL g[N], mu[N], s[N], n;
I LL getg(LL x) { return x
//min_25
#include
using namespace std;
//#define Toocold
#define I inline
#define lc o<<1
#define rc o<<1|1
#define fi first
#define se second
#define pb push_back
#define ALL(X) (X).begin(), (X).end()
#define bcnt(X) __builtin_popcountll(X)
#define CLR(A, X) memset(A, X, sizeof(A))
using DB = double;
using LL = long long;
using PII = pair;
#ifdef Toocold
#define dbg(args...)\
do { cout << "DEBUG: " << #args << " -> "; err(args); } while(0)
#else
#define dbg(...)
#endif // Toocold
void err() { puts(""); }
template class T, typename t, typename... Args>
void err(T a, Args... args) { for(auto x:a) cout << x << ' '; err(args...); }
template
void err(T a, Args... args) { cout << a << ' '; err(args...); }
/*-----------------------------------------------------------------------------*/

const int N = 1e6+10;

LL tmp;
int p[N], pnt;
bool isn[N];
vector fac;

void init() {
    isn[1] = 1;
    for(int i = 2; i < N; i++) {
        if(!isn[i]) p[pnt++] = i;
        for(int j = 0; j val[j]) break;
            LL now = val[j]/p[i];
            now = now>B?idr[n/now]:idl[now];
            G[j] = G[j]-(G[now]-pG[i-1]);
        }
        for(int i = 1; i <= cnt; i++) {
            G[i] = -(G[i]-(upper_bound(ALL(fac), val[i])-fac.begin()));
            dbg(G[i]);
        }
    }

    LL S(LL x, int k) {
        if(x<=1 || p[k]>x) return 0;
        LL ans = (G[x<=B?idl[x]:idr[n/x]]-F[k-1]);
        for(int i = k; i<=pnt && p[i]*p[i]<=x; i++) if(!find(p[i]))
        for(LL t = p[i], e = 1; t*p[i] <= x; t*=p[i], e++)
            ans = (ans+S(x/t, i+1)*f(p[i], e)+f(p[i], e+1));
        return ans;
    }

    I LL sum(LL x) {
        init(x);
        return S(x, 1)+1;
    }
}

I void work() {
    LL m, n; scanf("%lld%lld", &m, &n);
    int u = 1;
    for(int i = 0; 1LL*p[i]*p[i] <= n; i++) if(n%p[i] == 0) {
        n /= p[i]; u *= -1;
        fac.pb(p[i]);
        if(n%p[i] == 0) { u = 0; break; }
    }
    if(n != 1) u *= -1, fac.pb(n);
    printf("%lld\n", u*min_25::sum(m));
}

int main() {
    init();
    work();
    return 0;
}


你可能感兴趣的:(数论-莫比乌斯反演,数论-杜教筛/min_25筛)