2017.6.5 YY的GCD 失败总结

                  这个题推式子还是比较正常的


要推式子 解这种题 需要抓住三个要点:

1、利用约数和倍数关系

2、换Σ

3、乘法优化加法(尽量往 商的值相同合并 上靠)、


注意:处理T的约数d的mu值和时不能用线筛直接求,因为线筛不一定遍历所有约数、

附上一段我的反例:


              

码:

#include<iostream>
#include<cstdio>
using namespace std;
#include<algorithm>
#include<cstring>
long long mu[10000005],qsum[10000005],su[10000005],tot,i,j,n,m,T;
bool he[10000005];
void eular()
{
	mu[1]=1;
//	qsum[1]=1;
	//memset(qsum,1,sizeof(qsum));
	//cout<<qsum[1];
	for(i=2;i<=10000000;i++)
	{    //qsum[i]++;
		if(!he[i])
		{
			//he[i]=1;
			su[++tot]=i;//if(i==7)cout<<"pp";
			mu[i]=-1;
		//	qsum[i]+=mu[1];	
		}
		for(j=1;j<=tot&&su[j]*i<=10000000;j++)
	   {
	   	he[su[j]*i]=1;
	   	if(i%su[j]==0)
		   {
		   	mu[i*su[j]]=0;break;
		   //	qsum[i*su[j]]+=mu[i];
		  // 	if(!he[i]&&i!=su[j])qsum[i*su[j]]+=mu[su[j]];
		   }else 
		     {
		     	mu[i*su[j]]=-mu[i];	
			//	 qsum[i*su[j]]+=mu[i];	
		//	if(!he[i]&&i!=su[j])qsum[i*su[j]]+=mu[su[j]];
			 }//if(su[j]*i==42)cout<<su[j]<<" "<<mu[su[j]]<<endl;	
		      }
	}
}
long long  work(int l,int r)
{
	long long  ans=0;
	 long long lin;
	if(l>r)swap(l,r);
	for(i=1;i<=l;i=lin+1)
	{
	lin=min(l/(l/i),r/(r/i));
	ans+=(qsum[lin]-qsum[i-1])*(l/i)*(r/i);
	//cout<<ans<<" "<<i-1<<"   ";
    }
	return ans;
}
int main()
{
    eular();
	for(i=1;i<=tot;i++)
	for(j=1;j*su[i]<=10000000;j++)qsum[j*su[i]]+=mu[j];
 	for(i=1;i<=10000000;i++)qsum[i]+=qsum[i-1];
	scanf("%lld",&T);
	while(T--)
	{
		scanf("%lld%lld",&n,&m);
		printf("%lld\n",work(n,m));
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值