非整除序列

题意

定义S(N)为最小的不能整除N 的正整数,接下再计算S(S(N))、S(S(S(N)))直到得到数字2。定义strength(N)为上述过程得到的序列长度。如N=6 时得到的序列为6,4,3,2,strength(6)=4。给定两个正整数A,B,A < B,计算strength(A)+strength(A+1)+…+strength(B)。

3A<B1017

分析

每个数的序列第一个数是它自己,我们要知道的就是它第二个数是什么。我们可以发现,若一个数X,它序列的第二个数为y,则X 为 Py1 的倍数,且X不为 Py 的倍数。其中 Pi 为2~i的所有数的最小公倍数,对于一个数 Pi ,我们可以知道区间内它的倍数有多少个。并且计算发现, i 做到41左右就会大于最大值了。

#include <cstdio>

const int N = 45;
typedef long long LL;
int f[N];
LL l,r;

LL calc(LL x) {
    if (x == 2) return 1;
    if (x <= N) {
        if (f[x]) return f[x];
        for (int i = 2;i <= N;i ++) if (x % i != 0) return f[x] = calc(i) + 1;
    }
    for (int i = 2;i <= N;i ++) if (x % i != 0) return calc(i) + 1;
}

LL count(LL l,LL r,LL x) {
    return r / x - (l - 1) / x;
}

LL gcd(LL a,LL b) {
    if (b == 0) return a;
    return gcd(b,a % b);
}

int main() {
    scanf("%lld%lld",&l,&r);
    LL last = 1,cur = 1,ans = 0;
    for (LL i = 2;i <= N;i ++) {
        if (last > r) break;
        cur = cur * i / gcd(cur,i);
        ans += (calc(i) + 1) * (count(l,r,last) - count(l,r,cur));
        last = cur;
    }
    printf("%lld\n",ans);
}

你可能感兴趣的:(非整除序列)