#include<bits/stdc++.h> #define N 5000010 #define yql 1000000007 using namespace std; typedef long long ll; int T,k,n[2010],m[2010],maxn,vis[N],prime[N]; int mu[N],cnt=0,fac[N]; ll f[N],s[N]; inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); return f*x; } inline ll fpow(ll x,ll p){ x%=yql;ll ans=1; for(;p;p>>=1,x=x*x%yql)if(p&1)ans*=x,ans%=yql; return (ans+yql)%yql; } void calcmu(){ cnt=0;mu[1]=1;s[1]=1;memset(vis,1,sizeof(vis)); for(int i=2;i<=maxn;i++){ if(vis[i]){prime[++cnt]=i;fac[i]=i;mu[i]=-1;f[i]=fpow(i,k);s[i]=f[i]-1;} for(int j=1;j<=cnt;j++){ int p=prime[j],t=i*p;if(t>maxn)break; vis[t]=0; if(i%p==0){ mu[t]=0;fac[t]=fac[i]*p; s[t]=1LL*s[i]*f[prime[j]]%yql; break; } mu[t]=-mu[i];s[t]=1LL*s[i]*s[p]%yql; } } for(int i=1;i<=maxn;i++)mu[i]+=mu[i-1],s[i]+=s[i-1],s[i]%=yql; } int main(){ T=read();k=read(); for(int i=1;i<=T;i++){ n[i]=read(),m[i]=read(); maxn=max(maxn,max(n[i],m[i])); } calcmu(); for(int i=1;i<=T;i++){ int nn=n[i],mm=m[i];if(nn>mm)swap(nn,mm); ll ans=0; for(int i=1,j=1;i<=nn;i=j+1){ j=min(mm/(mm/i),nn/(nn/i)); ans+=(s[j]-s[i-1]+yql)%yql*(nn/i)%yql*(mm/i)%yql;ans%=yql; } printf("%lld ",ans); } }
试了下maxn操作,结果还是BZOJ倒数TAT
感觉式子化得没问题啊?