拓展φ

样例输入

11 10

样例输出

10
5
7
5
8
3
9
5
7
4
10

 (嘻嘻嘻,求助了几位dalao才弄懂得,必须要纪念一下)

这道题就是利用容斥原理啊

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 100005;
int n, prime[N], tot, cnt;
bool vis[N];
ll m, num[N], ans;

void getprime() {
    for (int i = 2; i <= n; i++) {
        if (!vis[i])
            prime[++tot] = i;
        for (int j = 1; j <= tot && i * prime[j] <= n; j++) {
            vis[i * prime[j]] = true;
            if (i % prime[j] == 0)
                break;
        }
    }
}

void work(int n) {
    for (int i = 1; i <= tot && prime[i] <= n; i++) {
        int x = prime[i];
        if (n % x == 0) {
            num[++cnt] = x;// 
            while (n % x == 0)
                n /= x;
        }
    }
}

//减掉与其不互质的,余下的就是互质的个数啦 
//不互质的咋减呢,找他的质因子喽,同样有这个质因子的肯定跟他不互质啦
void dfs(int a, int p, int s) {//p约数,s为正负1(加还是减) 
    if (!a) {
        ans += (ll)s * m / p; // m/p是m中p的倍数的个数 
        return;
    }
    //看质因数个数,一个->加,两个->减,三个->加... 
    dfs(a - 1, p, s);
    dfs(a - 1, p * num[a], -1 * s);
    /*比如有因数3,4,5 
                     1
                  /     \
                /         \
               3            1
             /   \        /   \ 
           3*4    3      4     1
          / \    / \    / \   / \
      3*4*5 3*4 3*5 3  4*5 4 5   1
    */
}

signed main() {
    cin >> n >> m;
    getprime();//质数表 
    for (int i = 1; i <= n; i++) {
        ans = 0;
        cnt = 0;//质因子个数 
        work(i);//求i的质因子个数 
        dfs(cnt, 1, 1);
        printf("%lld\n", ans);
    }
}

猜你喜欢

转载自www.cnblogs.com/aprincess/p/11805792.html