P1829 [国家集训队]Crash的数字表格 / JZPTAB

求值:

易得原式如下:

枚举最大公因数:

非常经典的式子的化法:

式子的后半段出现了互质数对之积之和,考率先单独拿出来,记

有:

观察上式,前半段可以预处理前缀和;后半段又是一个范围内数对之和,记

可以求解。

至此:

我们可以数论分块求解这部分。

回到定义的地方,则原式为:

这又是一个可以数论分块求解的式子。

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e7+7,mod=20101009;
int mu[maxn];
ll f[maxn];
int g(ll x,ll y) {
    return (x*(x+1)/2%mod)*(y*(y+1)/2%mod)%mod;
}
int sum(int n,int m) {
    int res(0);
    for(int d=1,x,y,r;d<=n;++d) {
        x=n/d,y=m/d;
        r=min(n/x,m/y);
        res=(res+(f[r]-f[d-1])*g(x,y))%mod;
        d=r;
    }
    return res;
}
bool vis[maxn];
vector<int>prime;
inline void init(int n) {
    f[1]=mu[1]=1;
    for(int i=2;i<=n;++i) {
        if(!vis[i]) {
            prime.emplace_back(i); mu[i]=-1;
        }
        for(auto &j:prime) {
            if(i*j>n) break;
            vis[i*j]=1;
            if(i%j==0) break;
            mu[i*j]=-mu[i];
        }
        f[i]=(f[i-1]+(ll)i*i*mu[i])%mod;
    }
}
signed main() {
    cin.sync_with_stdio(false), cin.tie(nullptr),cout.tie(nullptr);
    int n,m;
    cin>>n>>m;
    if(n>m) swap(n,m);//便于处理
    init(n);
    int ans(0);
    for(int d=1,x,y,r;d<=n;++d) {
        x=n/d,y=m/d;
        r=min(n/x,m/y);
        ans=(ans+(ll)(r+d)*(r-d+1)/2*sum(x,y))%mod;
        d=r;
    }
    cout<<(ans+mod)%mod<<'\n';
    return 0;
}

图片说明

这题线性筛比普通筛快很多。

莫比乌斯反演 文章被收录于专栏

NULL

全部评论

相关推荐

程序员牛肉:1.大头肯定是院校问题,这个没啥说的。 2.虽然有实习,但是实习的内容太水了,在公司待了七个月的时间,看起来就只做了jwt和接入redis。爬取新闻,数据导入。这几个需求值得你做七个月吗?这不就是三四个月的工作量吗?我要是面试官的话真心会认为你能力不太行。所以既然有实习了,一定要好好写,像是Swagger这种东西是真没必要写上去,就拉一个包的事情。 3.我个人觉得话,在校生不要把自己当社招看,除非你的项目是特别牛逼,特别有名的含金量,否则不要写这种密密麻麻的一串子工作职责。你的项目只有一个作用,就是供面试官从中来抽取八股对你进行拷打。 但是你现在这个看不来什么技术点,可以改一下,详细表述一下你用什么技术实现了什么功能,在实现这个功能的过程中,你解决了什么难题。
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-17 14:06
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务