NC53408. 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); }