SPOJ 4491. Primes in GCD Table 【mobius反演】

来源:互联网 发布:霍金对人工智能看法 编辑:程序博客网 时间:2024/05/18 18:02

莫比乌斯反演应该是数论中比较有意思的东西了,和容斥原理有点像,但又完全不同

使用它可以化简很多问题的计算

定理:是定义在非负整数集合上的两个函数,并且满足条件,那么我们得到结论

 

     

 

在上面的公式中有一个函数,它的定义如下:

 

    (1)若,那么

    (2)若均为互异素数,那么

    (3)其它情况下

 

 

对于函数,它有如下的常见性质:

 

    (1)对任意正整数

  

                            

 

        (2)对任意正整数

 

         

 

证明

 


#pragma comment(linker, "/STACK:102400000,102400000")#include<iostream>#include<vector>#include<algorithm>#include<cstdio>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<cmath>#include<cassert>#include<cstring>#include<iomanip>using namespace std;#ifdef _WIN32#define i64 __int64#define out64 "%I64d\n"#define in64 "%I64d"#else#define i64 long long#define out64 "%lld\n"#define in64 "%lld"#endif/************ for topcoder by zz1215 *******************/#define foreach(c,itr)  for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)#define FF(i,a)         for( int i = 0 ; i < (a) ; i ++)#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)#define S64(a)          scanf(in64,&a)#define SS(a)           scanf("%d",&a)#define LL(a)           ((a)<<1)#define RR(a)           (((a)<<1)+1)#define pb              push_back#define pf              push_front#define X               first#define Y               second#define CL(Q)           while(!Q.empty())Q.pop()#define MM(name,what)   memset(name,what,sizeof(name))#define MC(a,b)memcpy(a,b,sizeof(b))#define MAX(a,b)        ((a)>(b)?(a):(b))#define MIN(a,b)        ((a)<(b)?(a):(b))#define read            freopen("out.txt","r",stdin)#define write           freopen("out2.txt","w",stdout)const int inf = 0x3f3f3f3f;const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;const double oo = 10e9;const double eps = 10e-6;const double pi = acos(-1.0);const int maxn = 10001111;int a, b;int prime[maxn];int mu[maxn];int tpmu[maxn];int stpmu[maxn];bool check[maxn];int tot;void init(){mu[1] = 1;tot = 0;for (int i = 2; i < maxn; i++){if (!check[i]){prime[tot++] = i;mu[i] = -1;}for (int j = 0; j < tot; j++){if (prime[j] * i>maxn) break;check[prime[j] * i] = true;if (i%prime[j] == 0){mu[prime[j] * i] = 0;break;}else{mu[prime[j] * i] = -mu[i];}}}int c;for (int i = 0; i < tot; i++){c = 1;for (int now = prime[i]; now < maxn; now+=prime[i],c++){tpmu[now] += mu[c];}}for (int i = 1; i < maxn; i++){stpmu[i] = stpmu[i - 1] + tpmu[i];}}int main(){init();int T;cin >> T;while (T--){cin >> a >> b;i64 ans = 0; int temp;for (int i = 1; i <= min(a, b); i=temp+1){temp = min(a / (a / i), b / (b / i));ans += (i64)(a / i)*(i64)(b / i)*(stpmu[temp] - stpmu[i - 1]);}cout << ans << endl;}return 0;}





0 0