洛谷P2568 GCD(歐拉線性篩 + 歐拉函數 + 前綴和)

2020.6.22
佔個坑等會寫。(9:20)

好了我回來了,窩快餓死了耶(11:59)

好了,不出所料地一道題沒寫出來。看了兩道dp感覺都非常容易想,然後就光榮掛了。看題解發現大家的答案都比我少一維,我自閉了。別人100我30分,大概這就是差距吧。早上看到了一道題,就是這個,剛開始看到本來想對質數表和前綴和進行二分。後來用突然想到可以在製作線性表的時候可以對質數統計答案,所有在n之前的質數的倍數進行統計答案。過了樣例,之後只有30pt。我仔細品了一下我的程序發現我好像沒有考慮倍數的倍數gcd不爲1這個問題。好吧,重新搞嘛,直接統計一下倍數和倍數之間的關係然後特判,自己鼓搗了一個t了兩個點的答案。看題解發現其實這道題有更聰明的辦法可以解決,然而那個時候我並不知道啥是歐拉函數phi,只知道推狄雷克利卷積和莫比烏斯反演的時候會用到。然後仔細研究了一小會(一個小時)才明白這個函數到底是幹什麼的,wtcl。

然後就線性地水過去了hhhhh

下學期到底怎麼辦還待定,建議我已經寫了,看學校能不能採納就是了。這個安排真的就離譜。家鄉一天20例如臨大敵,學校停課工廠停工,學校所在的鎮子一天200+照樣開學。也可以說是一種看透了自身條件之後的權宜之計把。但這一切真的不可避免麼??我想肯定不是的。如果能早一點採取干預性措施,斷然不是這個結果。這不是一場感冒,感染上就意味着你和你最親近的人有5%的機率會看不到明年的icpc wf。希望學校不要再這麼兒戲了。

且不說我們能不能順利到了校園,路上風險和隔離30天就讓我沒啥到校地興趣和動力。自己學他不好嘛??但願人沒事兒。

代碼:

#include <bits/stdc++.h>
using namespace std;
#define limit (10000000 + 5)//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f
#define lowbit(i) i&(-i)//一步兩步
#define EPS 1e-6
#define FASTIO  ios::sync_with_stdio(false);cin.tie(0);
#define ff(a) printf("%d\n",a );
#define pi(a,b) pair<a,b>
#define rep(i, a, b) for(int i = a; i <= b ; ++i)
#define per(i, a, b) for(int i = b ; i >= a ; --i)
#define mint(a,b,c) min(min(a,b), c)
#define MOD 998244353
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\acm_01\\data.txt", "rt", stdin)
typedef long long ll;
typedef unsigned long long ull;
ll read(){
    ll sign = 1, x = 0;char s = getchar();
    while(s > '9' || s < '0' ){if(s == '-')sign = -1;s = getchar();}
    while(s >= '0' && s <= '9'){x = x * 10 + s - '0';s = getchar();}
    return x * sign;
}//快讀
void write(ll x){
    if(x < 0) putchar('-'),x = -x;
    if(x / 10) write(x / 10);
    putchar(x % 10 + '0');
}
int n,m,k;
int num[limit];
int prime[limit],tot;
ll ans;
ll phi[limit],sum[limit];
void make_prime(int N = 1e7){
    memset(num, 1, sizeof(num));
    num[1] = num[0] = 0;
    tot = 0;
    phi[1] = 1;
    rep(i, 2,N){
        if(num[i])prime[++tot] = i,phi[i] = i - 1;
        for(ll j = 1; j <= tot && i * prime[j] <= N; ++j){
            num[i * prime[j]] = 0;
            if(gcd(prime[j] , i) == 1){
                phi[prime[j] * i] = phi[prime[j]] * phi[i];
            }else{
                phi[prime[j] * i] = prime[j] * phi[i];
            }
            if(i % prime[j] == 0)break;//斷開
        }
    }
}//歐拉篩
int main() {
#ifdef LOCAL
    FOPEN;
#endif
    n = read();
    ans = 0;
    make_prime(n);
    rep(i ,1, n){
        sum[i] = phi[i] + sum[i - 1];
    }
    rep(i ,1,tot){
        ans += 2 * sum[n / prime[i]] - 1;
    }
    write(ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章