莫比乌斯反演
发现搞出来的式子和昨天的差不多
#include
#include
#include
using namespace std;
const
int mod=1000000007;
const
int maxn=5000001;
bool check[maxn];
int sq[maxn],prime[maxn],G[maxn],Pre[maxn],mu[maxn];
int tot;
char c;
inline void read(int &a)
{a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}
int main()
{
int T,tp,K,i,j,k,l;
read(T),read(K);
sq[1]=1;
for(i=2;isq[i]=1;
for(j=1;l;j<<=1,tp=(tp*1ll*tp)%mod)
if(l&j)l^=j,sq[i]=(sq[i]*1ll*tp)%mod;
}
for(i=2;iif(!check[i])
G[i]=sq[i]-1,prime[++tot]=i;
for(j=1;j<=tot;j++)
{
if(i*1ll*prime[j]>=maxn)break;
check[i*prime[j]]=true;
if(i%prime[j]==0){G[i*prime[j]]=(sq[prime[j]]*1ll*G[i])%mod;break;}
else G[i*prime[j]]=((sq[prime[j]]-1ll)*G[i])%mod;
}
}
G[1]=1;
for(i=1;i1]+G[i])%mod;
int next,n,m,Div1,Div2;
long long ans;
while(T--)
{
read(n),read(m);
if(n>m)swap(n,m);
tp=1;
ans=0;
while(tp<=n)
{
Div1=n/tp;
i=n/Div1+1;
Div2=m/tp;
j=m/Div2+1;
next=min(i,j);
ans=(ans+(Div1*1ll*Div2)%mod*((Pre[next-1]-Pre[tp-1]+mod)%mod))%mod;
tp=next;
}
printf("%lld\n",ans);
}
return 0;
}
突然度教说只需要处理质数的p次方就好了
对啊!!
#include
#include
using namespace std;
const
int mod=1000000007;
const
int maxn=5000001;
bool check[maxn];
int sq[maxn],prime[maxn],G[maxn],Pre[maxn],mu[maxn];
int tot;
char c;
inline void read(int &a)
{a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}
int main()
{
int T,tp,K,i,j,k,l;
read(T),read(K);
sq[1]=1;
for(i=2;iif(!check[i])
{
tp=i;
l=K;
sq[i]=1;
for(j=1;l;j<<=1,tp=(tp*1ll*tp)%mod)
if(l&j)l^=j,sq[i]=(sq[i]*1ll*tp)%mod;
G[i]=sq[i]-1,prime[++tot]=i;
}
for(j=1;j<=tot;j++)
{
if(i*1ll*prime[j]>=maxn)break;
check[i*prime[j]]=true;
if(i%prime[j]==0){G[i*prime[j]]=(sq[prime[j]]*1ll*G[i])%mod;break;}
else G[i*prime[j]]=((sq[prime[j]]-1ll)*G[i])%mod;
}
}
G[1]=1;
for(i=1;i1]+G[i])%mod;
int next,n,m,Div1,Div2;
long long ans;
while(T--)
{
read(n),read(m);
if(n>m)swap(n,m);
tp=1;
ans=0;
while(tp<=n)
{
Div1=n/tp;
i=n/Div1+1;
Div2=m/tp;
j=m/Div2+1;
next=min(i,j);
ans=(ans+(Div1*1ll*Div2)%mod*((Pre[next-1]-Pre[tp-1]+mod)%mod))%mod;
tp=next;
}
printf("%lld\n",ans);
}
return 0;
}