bzoj 2694: Lcm
2694: Lcm
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 422 Solved: 220
[Submit][Status][Discuss]
Description
对于任意的>1的n gcd(a, b)不是n^2的倍数
也就是说gcd(a, b)没有一个因子的次数>=2
也就是说gcd(a, b)没有一个因子的次数>=2
Input
一个正整数T表示数据组数
接下来T行 每行两个正整数 表示N、M
Output
T行 每行一个整数 表示第i组数据的结果
Sample Input
4
2 4
3 3
6 5
8 3
2 4
3 3
6 5
8 3
Sample Output
24
28
233
178
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; }
我爱学习,学习使我快乐