2017.9.26 于神之怒加强版 失败总结

、这个题直接上反演可以化成:

2017.9.26 于神之怒加强版 失败总结_第1张图片

然后后面的部分是可以预处理的,最简单的预处理是nlogn的,理论能过,但不知为何死活过不了、

所以就需要o(n)来求后面函数的值

设f=∑d|t  mu(d)*(T/d)^k   这是一个狄利克雷卷积。。

然后由于(T/d)^k 是积性函数、mu是积性函数  所以f也是积性函数

然后记录g【i】为最小质因子的最高次幂的值,就可以筛f了


码(+1-1的需要结合mu的取值理解):

#include
#include
using namespace std;
#define P 1000000007 
long long daan;
#define N 5000005
#define ll long long 
ll f[N],su[N],g[N],last,i,j,T,n,k,tot,sum[N],m,q1[N],q2[N],cnt;
bool he[N];
int ksm(ll a,int b)
{
	ll ans=1;
	while(b)
	{
	if(b&1)ans=ans*a%P;
	  b>>=1;
	  a=a*a%P;			
	}	
	return ans;	
}
void eular(int o)
{
	f[1]=1;
	for(i=2;i<=o;i++)
	{
	if(!he[i])
	{
	su[++tot]=i;
//	mu[i]=-1;	
   g[i]=i;
   f[i]=(ksm(i,k)+P-1)%P;	
	}	
	for(j=1;j<=tot&&su[j]*i<=o;j++)	
	{
	
	he[i*su[j]]=1;
 	
	if(i%su[j]==0)
	{	g[i*su[j]]=g[i]*g[su[j]];
	//	mu[i*su[j]]=0;
	if(i==g[i])f[su[j]*i]=f[i]*(f[su[j]]+1)%P;
	else f[su[j]*i]=f[i/g[i]]*f[g[i]*su[j]]%P;
		break;
	}else 
	{ g[i*su[j]]=su[j];
	  f[i*su[j]]=f[i]*f[su[j]]%P;
	}	
	}		
	}
//for(i=1;i<=o;i++)g[i]=ksm(i,k);	

for(i=1;i<=o;i++)
{
	sum[i]=(f[i]+sum[i-1])%P;
}
}
int main()
{
	scanf("%d%d",&T,&k);
	ll o=0;
	for(i=1;i<=T;i++)
	{
		scanf("%lld%lld",&q1[i],&q2[i]);
		o=max(o,q1[i]);
		o=max(o,q2[i]);			
	}
	eular(o);
	int j;
	for(j=1;j<=T;j++)
	{
		daan=0;
		//scanf("%lld%lld",&n,&m);
		n=q1[j];
		m=q2[j];
		if(n>m)swap(n,m);
		for(i=1;i<=n;i=last+1)
		{
			last=min(n/(n/i),m/(m/i));
			daan=(daan+(sum[last]-sum[i-1])*(m/i)%P*(n/i))%P;
		}	
	printf("%lld\n",(daan+P)%P);	
	}
}



你可能感兴趣的:(题目)