上套路
-
反演
-
-
-
-
-
-
51Nod 1244 - 莫比烏斯函數之和
51Nod 1239 - 歐拉函數之和
51Nod 1237 - 最大公約數之和 V3
51Nod 1238 - 最小公倍數之和 V3
51Nod 1227 - 平均最小公倍數
51Nod 1220 - 約數之和
HDU 6706 - huntian oy
洛谷 P2257 - YY的GCD
51Nod 1244 - 莫比烏斯函數之和
回目錄
杜教篩,捲上恆等函數
則
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
int su[N],mu[N],num,vis[N];
unordered_map<LL,LL> mp;
void init()
{
mu[1]=1;
for(int i=2;i<N;++i){
if(!vis[i])su[++num]=i,mu[i]=-1;
for(int j=1;j<=num&&i*su[j]<N;++j){
vis[i*su[j]]=1;
if(i%su[j]==0)break;
mu[i*su[j]]=-mu[i];
}
}
for(int i=1;i<N;++i)mu[i]+=mu[i-1];
}
LL djs(LL n)
{
if(n<N)return mu[n];
if(mp[n])return mp[n];
LL ans=1;
for(LL L=2,R;L<=n;L=R+1){
R=n/(n/L);
ans-=(R-L+1)*djs(n/L);
}
return mp[n]=ans;
}
int main()
{
init();
LL L,R;
scanf("%lld%lld",&L,&R);
printf("%lld\n",djs(R)-djs(L-1));
return 0;
}
51Nod 1239 - 歐拉函數之和
回目錄
杜教篩,捲上恆等函數
則
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
int su[N],phi[N],num,vis[N];
unordered_map<LL,LL> mp;
const LL mod=1e9+7;
const LL inv2=500000004;
void init()
{
phi[1]=1;
for(int i=2;i<N;++i){
if(!vis[i])su[++num]=i,phi[i]=i-1;
for(int j=1;j<=num&&i*su[j]<N;++j){
vis[i*su[j]]=1;
if(i%su[j]==0){
phi[i*su[j]]=phi[i]*su[j];
break;
}
phi[i*su[j]]=phi[i]*phi[su[j]];
}
}
for(int i=1;i<N;++i)phi[i]=(phi[i]+phi[i-1])%mod;
}
LL sum(LL n)
{
n%=mod;
return n*(n+1)%mod*inv2%mod;
}
LL djs(LL n)
{
if(n<N)return phi[n];
if(mp[n])return mp[n];
LL ans=sum(n);
for(LL L=2,R;L<=n;L=R+1){
R=n/(n/L);
ans=(ans-(R-L+1)%mod*djs(n/L)%mod+mod)%mod;
}
return mp[n]=ans;
}
int main()
{
init();
LL n;
scanf("%lld",&n);
printf("%lld\n",djs(n));
return 0;
}
51Nod 1237 - 最大公約數之和 V3
回目錄
杜教篩加分塊即可
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
int su[N],phi[N],num,vis[N];
unordered_map<LL,LL> mp;
const LL mod=1e9+7;
const LL inv2=500000004;
void init()
{
phi[1]=1;
for(int i=2;i<N;++i){
if(!vis[i])su[++num]=i,phi[i]=i-1;
for(int j=1;j<=num&&i*su[j]<N;++j){
vis[i*su[j]]=1;
if(i%su[j]==0){
phi[i*su[j]]=phi[i]*su[j];
break;
}
phi[i*su[j]]=phi[i]*phi[su[j]];
}
}
for(int i=1;i<N;++i)phi[i]=(phi[i]+phi[i-1])%mod;
}
LL sum(LL n)
{
n%=mod;
return n*(n+1)%mod*inv2%mod;
}
LL djs(LL n)
{
if(n<N)return phi[n];
if(mp[n])return mp[n];
LL ans=sum(n);
for(LL L=2,R;L<=n;L=R+1){
R=n/(n/L);
ans=(ans-(R-L+1)%mod*djs(n/L)%mod+mod)%mod;
}
return mp[n]=ans;
}
LL outside(LL n)
{
LL ans=0;
for(LL L=1,R;L<=n;L=R+1){
R=n/(n/L);
ans=(ans+(djs(R)-djs(L-1)+mod)%mod*((n/L)%mod)*((n/L)%mod)+mod)%mod;
}
return ans;
}
int main()
{
init();
LL n;
scanf("%lld",&n);
printf("%lld\n",outside(n));
return 0;
}
51Nod 1238 - 最小公倍數之和 V3
回目錄
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
const LL mod=1e9+7;
const LL inv2=500000004;
const LL inv6=166666668;
int su[N],num,vis[N];
LL phi[N];
unordered_map<LL,LL> mp;
void init()
{
phi[1]=1;
for(int i=2;i<N;++i){
if(!vis[i])su[++num]=i,phi[i]=i-1;
for(int j=1;j<=num&&i*su[j]<N;++j){
vis[i*su[j]]=1;
if(i%su[j]==0){
phi[i*su[j]]=phi[i]*su[j];
break;
}
phi[i*su[j]]=phi[i]*phi[su[j]];
}
}
for(int i=1;i<N;++i)phi[i]=(phi[i]*i%mod*i%mod+phi[i-1])%mod;
}
LL sum(LL n)
{
n%=mod;
return n*(n+1)%mod*inv2%mod;
}
LL get(LL n)
{
n%=mod;
return n*(n+1)%mod*(2*n+1)%mod*inv6%mod;
}
LL djs(LL n)
{
if(n<(LL)N)return phi[n];
if(mp[n])return mp[n];
LL ans=sum(n);
ans=ans*ans%mod;
for(LL L=2,R;L<=n;L=R+1){
R=n/(n/L);
ans=(ans-(get(R)-get(L-1)+mod)%mod*djs(n/L)%mod+mod)%mod;
}
return mp[n]=ans;
}
LL outside(LL n)
{
LL ans=0;
for(LL L=1,R;L<=n;L=R+1){
R=n/(n/L);
ans=(ans+(sum(R)-sum(L-1)+mod)%mod*djs(n/L)%mod+mod)%mod;
}
return ans;
}
int main()
{
init();
LL n;
scanf("%lld",&n);
printf("%lld\n",outside(n));
return 0;
}
51Nod 1227 - 平均最小公倍數
回目錄
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
const LL mod=1e9+7;
const LL inv2=500000004;
const LL inv6=166666668;
int su[N],num,vis[N];
LL phi[N];
unordered_map<LL,LL> mp;
void init()
{
phi[1]=1;
for(int i=2;i<N;++i){
if(!vis[i])su[++num]=i,phi[i]=i-1;
for(int j=1;j<=num&&i*su[j]<N;++j){
vis[i*su[j]]=1;
if(i%su[j]==0){
phi[i*su[j]]=phi[i]*su[j];
break;
}
phi[i*su[j]]=phi[i]*phi[su[j]];
}
}
for(int i=1;i<N;++i)phi[i]=(phi[i]*i%mod+phi[i-1])%mod;
}
LL sum(LL n)
{
n%=mod;
return n*(n+1)%mod*inv2%mod;
}
LL get(LL n)
{
n%=mod;
return n*(n+1)%mod*(2*n+1)%mod*inv6%mod;
}
LL djs(LL n)
{
if(n<(LL)N)return phi[n];
if(mp[n])return mp[n];
LL ans=get(n);
for(LL L=2,R;L<=n;L=R+1){
R=n/(n/L);
ans=(ans-(sum(R)-sum(L-1)+mod)%mod*djs(n/L)%mod+mod)%mod;
}
return mp[n]=ans;
}
LL outside(LL n)
{
LL ans=0;
for(LL L=1,R;L<=n;L=R+1){
R=n/(n/L);
ans=(ans+(R-L+1+mod)%mod*djs(n/L)%mod+mod)%mod;
}
return (ans+n)%mod*inv2%mod;
}
int main()
{
init();
LL n,m;
scanf("%lld%lld",&n,&m);
printf("%lld\n",(outside(m)-outside(n-1)+mod)%mod);
return 0;
}
51Nod 1220 - 約數之和
回目錄
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
const LL mod=1e9+7;
const LL inv2=500000004;
const LL inv6=166666668;
int su[N],num,vis[N],mu[N];
unordered_map<int,LL> mp;
void init()
{
mu[1]=1;
for(int i=2;i<N;++i){
if(!vis[i])su[++num]=i,mu[i]=-1;
for(int j=1;j<=num&&i*su[j]<N;++j){
vis[i*su[j]]=1;
if(i%su[j]==0)break;
mu[i*su[j]]=-mu[i];
}
}
for(int i=1;i<N;++i)mu[i]=(mu[i]*i+mu[i-1]+mod)%mod;
}
LL sum(int n)
{
return (LL)n*(n+1)%mod*inv2%mod;
}
LL djs(int n)
{
if(n<N)return mu[n];
if(mp[n])return mp[n];
LL ans=1;
for(int L=2,R;L<=n;L=R+1){
R=n/(n/L);
ans=(ans-(sum(R)-sum(L-1)+mod)%mod*djs(n/L)%mod+mod)%mod;
}
return mp[n]=ans;
}
LL inside(int n)
{
LL ans=0;
for(int L=1,R;L<=n;L=R+1){
R=n/(n/L);
ans=(ans+(sum(R)-sum(L-1)+mod)%mod*(n/L)%mod+mod)%mod;
}
return ans*ans%mod;
}
LL outside(int n)
{
LL ans=0;
for(int L=1,R;L<=n;L=R+1){
R=n/(n/L);
ans=(ans+(djs(R)-djs(L-1)+mod)%mod*inside(n/L)%mod+mod)%mod;
}
return ans;
}
int main()
{
init();
int n;
scanf("%d",&n);
printf("%lld\n",outside(n));
return 0;
}
HDU 6706 - huntian oy
回目錄
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e6+9;
const LL mod=1e9+7;
const LL inv2=500000004;
const LL inv6=166666668;
int su[N],num,vis[N];
LL phi[N];
unordered_map<int,LL> mp;
void init()
{
phi[1]=1;
for(int i=2;i<N;++i){
if(!vis[i])su[++num]=i,phi[i]=i-1;
for(int j=1;j<=num&&i*su[j]<N;++j){
vis[i*su[j]]=1;
if(i%su[j]==0){
phi[i*su[j]]=phi[i]*su[j];
break;
}
phi[i*su[j]]=phi[i]*phi[su[j]];
}
}
for(int i=1;i<N;++i)phi[i]=(phi[i]*i%mod+phi[i-1]+mod)%mod;
}
LL sum(int n)
{
return (LL)n*(n+1)%mod*inv2%mod;
}
LL djs(int n)
{
if(n<N)return phi[n];
if(mp[n])return mp[n];
LL ans=(LL)n*(n+1)%mod*(2*n+1)%mod*inv6%mod;
for(int L=2,R;L<=n;L=R+1){
R=n/(n/L);
ans=(ans-(sum(R)-sum(L-1)+mod)%mod*djs(n/L)%mod+mod)%mod;
}
return mp[n]=ans;
}
int main()
{
init();
int n,T,a,b;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&a,&b);
printf("%lld\n",(djs(n)-1+mod)%mod*inv2%mod);
}
return 0;
}
洛谷 P2257 - YY的GCD
回目錄
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e7+9;
const LL mod=1e9+7;
const LL inv2=500000004;
const LL inv6=166666668;
int mu[N],mm[N],su[N],num;
bool vis[N];
void init()
{
mu[1]=1;
for(int i=2;i<N;++i){
if(!vis[i])su[++num]=i,mu[i]=-1;
for(int j=1;j<=num&&i*su[j]<N;++j){
vis[i*su[j]]=1;
if(i%su[j]==0)break;
mu[i*su[j]]=-mu[i];
}
}
for(int i=1;i<=num;++i)
for(int j=1;su[i]*j<N;++j)mm[su[i]*j]+=mu[j];
for(int i=1;i<N;++i)mm[i]+=mm[i-1];
}
LL outside(int n,int m)
{
LL ans=0;
for(int L=1,R;L<=n;L=R+1){
R=min(n/(n/L),m/(m/L));
ans+=(LL)(n/L)*(m/L)*(mm[R]-mm[L-1]);
}
return ans;
}
int main()
{
init();
int T,n,m;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
if(n>m)swap(n,m);
printf("%lld\n",outside(n,m));
}
return 0;
}