bzoj 2694: Lcm

2694: Lcm

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 422  Solved: 220
[Submit][Status][Discuss]

Description

 

对于任意的>1的n gcd(a, b)不是n^2的倍数
也就是说gcd(a, b)没有一个因子的次数>=2

Input

一个正整数T表示数据组数
接下来T行 每行两个正整数 表示N、M

Output

T行 每行一个整数 表示第i组数据的结果

Sample Input

4
2 4
3 3
6 5
8 3

Sample Output

24
28
233
178

HINT

 

HINT

T <= 10000


N, M<=4000000

 
 
感谢DZM大爷借我权限号一用2333
然后发现 第三个条件 就是要求gcd没有平方因子,所以写成 *μ^2(gcd(a,b)) 就行了,然后就是一个积性函数题了、、
 
#include<bits/stdc++.h>
#define ll long long
const int maxn=4000000;
const int ha=1<<30;
using namespace std;
int zs[maxn/5],t=0,T,n,m;
int low[maxn+5],f[maxn+5];
bool v[maxn+5];

inline int add(int x,int y){
	x+=y;
	return x>=ha?x-ha:x;
}

inline void init(){
	low[1]=f[1]=1;
	for(int i=2;i<=maxn;i++){
		if(!v[i]) zs[++t]=i,low[i]=i,f[i]=1-i;
		for(int j=1,u;j<=t&&(u=zs[j]*i)<=maxn;j++){
			v[u]=1;
			if(!(i%zs[j])){
				low[u]=low[i]*zs[j];
				if(!v[low[i]]) f[u]=f[i/low[i]]*-low[i];
				else f[u]=0; 
				break;
			}
			low[u]=zs[j];
			f[u]=f[i]*f[zs[j]];
		}
	}

	for(int i=1;i<=maxn;i++) f[i]=add(add(f[i],ha)*(ll)i%ha,f[i-1]);
}

inline int solve(){
	int an=0;
	if(n>m) swap(n,m);
	
	for(int i=1,nx,ny,j;i<=n;i=j+1){
		nx=n/i,ny=m/i,j=min(n/nx,m/ny);
		an=add(an,((nx+1)*(ll)nx>>1)%ha*(ll)(((ny+1)*(ll)ny>>1)%ha)%ha*(ll)add(f[j],ha-f[i-1])%ha);
	}
	
	return an;
}

int main(){
	init();
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&m);
		printf("%d\n",solve());
	}
	return 0;
}

  

posted @ 2018-03-16 08:53  蒟蒻JHY  阅读(211)  评论(0编辑  收藏  举报