首页 > 其他 > 详细

洛谷 - P4450 - 双亲数 - 整除分块

时间:2019-06-11 23:00:45      阅读:106      评论:0      收藏:0      [点我收藏+]

https://www.luogu.org/fe/problem/P4450

应该不分块也可以。

\(F(n,m,d)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[gcd(i,j)==d]\)

模板题,直接套。

但是我的分块的上界忘记把n和m换过来了。

实验证明每次都要取min,不是一蹴而就的把n换到小的然后让r赋值n。

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

const int MAXN=1e6;
int pri[MAXN+1];
int &pritop=pri[0];
int mu[MAXN+1];
void sieve(int n=MAXN) {
    pritop=0;
    mu[1]=1;
    for(int i=2; i<=n; i++) {
        if(!pri[i])
            pri[++pritop]=i,mu[i]=-1;
        for(int j=1; j<=pritop; j++) {
            int &p=pri[j];
            int t=i*p;
            if(t>n)
                break;
            pri[t]=1;
            if(i%p)
                mu[t]=-mu[i];
            else {
                mu[t]=0;
                break;
            }
        }
    }
    for(int i=1;i<=n;i++)
        mu[i]+=mu[i-1];
}

ll F(int n,int m,int d){
    ll res=0;
    int nm=min(n,m);
    for(int l=1,r;l<=nm;l=r+1){
        int tn=n/l;
        int tm=m/l;
        r=min(n/tn,m/tm);
        res+=1ll*(mu[r]-mu[l-1])*(tn/d)*(tm/d);
    }
    return res;
}

int main() {
#ifdef Yinku
    freopen("Yinku.in","r",stdin);
#endif // Yinku
    sieve();
    int n,m,d;
    scanf("%d%d%d\n",&n,&m,&d);
    if(d==0)
        puts("0\n");
    else
        printf("%lld\n",F(n,m,d));
    return 0;
}

洛谷 - P4450 - 双亲数 - 整除分块

原文:https://www.cnblogs.com/Yinku/p/11006766.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!