洛谷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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章