质因子&容斥原理求与n互质的个数

  • 求一个数的质因子

//求一个数的质因子,将质因子储存在a[],并返回质因子的个数
int init(ll n) {
    ll i;
    idx = 0;
    for (i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            a[idx++] = i;
            while (n % i == 0)
                n = n / i;
        }
    }
    if (n > 1)//这里要记得
        a[idx++] = n;
    return idx - 1;
}
  • 求[1,m]内与n互质的个数(容斥原理)

//求[1,m]内与n互质的个数,用队列数组实现容斥原理
ll fid(ll m) {
    ll que[10000], k, t = 0, sum = 0;
    que[t++] = -1;
    for (ll i = 0; i < idx; i++) {
        k = t;
        for (ll j = 0; j < k; j++)
            que[t++] = que[j] * a[i] * (-1);
    }
    for (ll i = 1; i < t; i++)
        sum = sum + m / que[i];
    return sum;
}

题目:

HDU 4135

代码

ll a[1000], idx;

//求一个数的质因子,将质因子储存在a[],并返回质因子的个数
int init(ll n) {
    ll i;
    idx = 0;
    for (i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            a[idx++] = i;
            while (n % i == 0)
                n = n / i;
        }
    }
    if (n > 1)//这里要记得
        a[idx++] = n;
    return idx - 1;
}

//求[1,m]内与n互质的个数,用队列数组实现容斥原理
ll fid(ll m) {
    ll que[10000], k, t = 0, sum = 0;
    que[t++] = -1;
    for (ll i = 0; i < idx; i++) {
        k = t;
        for (ll j = 0; j < k; j++)
            que[t++] = que[j] * a[i] * (-1);
    }
    for (ll i = 1; i < t; i++)
        sum = sum + m / que[i];
    return sum;
}

int main() {
    ll T, x, y, n, sum;
    while (~scanf("%lld", &T)) {
        for (ll i = 1; i <= T; i++) {
            scanf("%lld%lld%lld", &x, &y, &n);
            init(n);
            sum = y - fid(y) - (x - 1 - fid(x - 1));
            printf("Case #%lld: ", i);
            printf("%lld\n", sum);
        }
    }
    return 0;
}
  • 求1~n的所有数的质因子

一次求出1~n的所有数的质因子,适用于题目中给的n个数比较多的,但是n不是很大的。

int visited[100010];
vector<int> a[100010];

void init() {
    int i, j;
    for (i = 0; i < 100010; i++)
        a[i].clear();//vector的清空
    memset(visited, 0, sizeof(visited));
    for (i = 2; i <= 100000; i++) {
        if (visited[i] == 0) { //i是素数这是可以保证的
            a[i].push_back(i);
            for (j = i + i; j <= 100000; j += i) {
                visited[j] = 1;
                a[j].push_back(i);
            }
        }
    }
}

int main() {
    int i, j;
    init();
    for (i = 0; i <= 50; i++) {
        printf("%d:", i);
        for (j = 0; j < a[i].size(); j++)
            printf("%d ", a[i][j]);
        printf("\n");
    }
    return 0;
}
发布了22 篇原创文章 · 获赞 0 · 访问量 555

猜你喜欢

转载自blog.csdn.net/skyyemperor/article/details/104727778