牛客网暑期ACM多校训练营(第三场)H - Diff-prime Pairs

题目链接
题意就不多说了

思路

  • 满足条件的只有素数和素数组合,因为素数和非素数的gcd = 1,两个数除以1之后,不能保证全为素数。
  • 知道只有素数组合之后,每次判断最大的素数,加入当前素数长度为len,那么这个最大的素数一共可以和len - 1个素数结合,因为可能存在素数的倍数,所以一共可以有 (len - 1) * (n / 素数)
  • 知道思路之后,for循环跑一下就ok

后记

比赛的时候想的复杂了,还好队友a了。。。


#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <map>
#include <bitset>
#include <set>
#include <string.h>
#include <cmath>
#include <queue>
#include <algorithm>
#define N 10000005
#define ll long long
#define lowbit(a) a&(-a)
#define pb(a) push_back(a)
#define mk(a, b) make_pair(a, b)
#define mem(a, b) memset(a, b, sizeof(a))
#define read(a) scanf("%d", &a)
#define print(a) printf("%d\n", a)
using namespace std;
int vis[N];
int main(){

#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    mem(vis, -1);
    vis[0] = vis[1] = 0;
    // 素数打表
    for (ll i = 2; i < N; ++i) {
        if (vis[i] == -1) {
            for (ll j = i * i; j < N; j += i) {
                vis[j] = 0;
            }
        }
    }
    int n;
    while(cin >> n) {
        vector<int> v;
        int len = 0;
        // 降序将素数push到vector中
        for (int i = n; i >= 2; --i) {
            if (vis[i] == -1)   v.push_back(i), ++len;
        }
        ll ans = 0;
        ll sum = len - 1;
        // 循环加
        for (int i = 0; i < len; ++i) {
            ans += (sum--) * (n / v[i]);
        }
        cout << ans * 2 << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/henuyh/article/details/81228031