列表

详情


NC53408. Forsaken遇到了毒瘤

描述

        Forsaken最近发现了一个有趣的整数集合,他把这个集合定义为。在这个集合中,所有的元素都满足表达式且不存在满足条件的不在集合中。有一天,一个毒瘤也发现了这个有趣的集合,于是毒瘤问Forsaken,对于一对,你能算出吗。(是约数和函数)。Forsaken觉得可以算,但没必要,所以这个问题给了你。由于答案可能非常大,你只需要输出在模意义下的结果。
        我本可以过得很快乐,直到我遇见了毒瘤。

输入描述

一行两个整数

输出描述

一行整数表示答案。

示例1

输入:

1 1

输出:

3

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 593ms, 内存消耗: 8320K, 提交时间: 2019-10-26 10:04:29

#include<bits/stdc++.h>
#define mod 1000000007
#define maxn 1000000
#define int long long
using namespace std;
int n,m,x;
int L,R;
int ans;
int s[1000005];
 
int calc(int x,int y){
    long long res=1ll*(x+y)*(y-x+1)/2;
    res%=mod;
    return res;
}
 
int solve(int x){
    if(x==0) return 0;
    if(x<=maxn) return s[x];
    int res=0;
    for(int l=1,r;l<=x;l=r+1){
        r=x/(x/l);
        res+=1ll*calc(l,r)*(x/l)%mod;
        if(res>=mod) res-=mod;
    }
    return res;
}
 
signed main(){
    cin>>n>>m;
    x=n+m;
    for(int i=1;i<=maxn;i++){
        for(int j=i;j<=maxn;j+=i){
            s[j]+=i;if(s[j]>=mod) s[j]-=mod;
        }
    }
    for(int i=1;i<=maxn;i++){
        s[i]+=s[i-1];
        if(s[i]>=mod) s[i]-=mod;
    }
    for(int l=1,r;l<=x;l=r+1){
        r=2e9;
        if(n/l!=0) r=min(r,n/(n/l));
        if(m/l!=0) r=min(r,m/(m/l));
        L=l,R=min((n+m)/(n/l+m/l+1),r);
        if(L<=R){
            ans=ans+solve(R);if(ans>=mod) ans-=mod;
            ans=ans+mod-solve(L-1);if(ans>=mod) ans-=mod;
        }
        if(n/l==0&&m/l==0) break;
    }
    cout<<ans<<endl;
     
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 581ms, 内存消耗: 16220K, 提交时间: 2019-10-29 20:24:26

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
const int N=2e6+7;
typedef long long ll;
ll f[N];
ll k(int n){
    if(n<N)return f[n];
    ll ans=0;
    for(ll i=1,last;i<=n;i=last+1){
        last=n/(n/i);
        ans+=(last-i+1)*(n/i)%mod;
        if(ans>=mod)ans%=mod;
    }
    return (ans%mod+mod)%mod;
}
ll _2(ll n){
    return n*(n+1)/2%mod;
}
ll Q(int n){
    ll ans=0;
    for(ll i=1,last;i<=n;i=last+1){
        last=n/(n/i);
        ll x=(_2(last)-_2(i-1)+mod)%mod*k(n/i)%mod;
        ans+=x;
        ans%=mod;
    }
    return (ans+mod)%mod;
}
int main(){
    for(int i=1;i<N;i++){
        for(int j=i;j<N;j+=i)f[j]++;
        f[i]+=f[i-1];
    }
    int n,m;
    cin>>n>>m;
    printf("%lld\n",((Q(n+m)-Q(n)-Q(m))%mod+mod)%mod);
}

上一题