spoj 4491. Primes in GCD Table 莫比乌斯反演
来源:互联网 发布:淘宝总部投诉客服电话 编辑:程序博客网 时间:2024/05/18 18:01
http://www.spoj.com/problems/PGCD/
题意: 给出 a ,b (1<=a,b <=10^7) ,求 gcd(x,y) =prime 的 方案数, 其中 1=<x<=a , 1<=x<=b 。
如果gcd(x ,y) = 1; 这个问题比较好求。
g(n) 为 gcd(x ,y) = n 的方案数。
f( n ) 为 gcd(x ,y) = b ,其中 n|b 的所有方案数
f( a ) = sigma( g( b )) 条件 a|b;
g( n ) = sigma( u(b)* f(b) ) n|b
u(b) =1 , b 是 Square-free Number 且 b是偶数个素因子的积
u(b) = 0 b 是 Square-free Number 且 b是寄数个素因子的积
u(b) = -1 b 是 不是 Square-free Number
f( n ) = a/n * b/n
g( n ) = sigma( u(t/n )*a/t* b/t);
ans = sigma( g( d )) ,d 是素数
ans = sigma{ u[ j ]* a/( d* j)* b/( d *j ) } d 是素数。
对于 x=p1^k1 * p2^k2 * p3^k3 ... 其中pi为素数。
当所有 ki全为1。那么从里面拿出一个素数d,会剩下一个Square-Free-Number。
1设x有t个素因子。取出一个后(其实就是 对于(a,b) 中, gcd(n)= 取值范围(a / n, b/ n) 中的gcd( 1) )而取法有t种于是ans+= ( ((t-1)&1)?-1:1 ) * t * (m/x) * (n/x)
2 当ki有一个是2,其它全是1 时, 所取的值只能是 ki等于2 的那个数,其余的都不会构成 square-free Number 。 所以取法仅一种。
那么显然 ans+=( (t&1)?-1:1 )*(m/x)*(n/x)
3 对于有多个2 的 x 不用考虑, 无论取那个都不是 square-free Number。
解法 对 u 进行打表, 求解过程中 分块求求值。
打表过程比较慢 程序 45s 。。 不解,本地跑得挺快的。。
#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <stack>#include <cstring>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio> #include <cstdlib>#include <ctime>#include <assert.h>#include <queue>#define REP(i,n) for(int i=0;i<n;i++)#define TR(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++)#define ALLL(x) x.begin(),x.end()#define SORT(x) sort(ALLL(x))#define CLEAR(x) memset(x,0,sizeof(x))#define FILLL(x,c) memset(x,c,sizeof(x))using namespace std; const double EPS = 1e-8; #define LL long long #define pb push_backconst int maxn = 10000001;int f[maxn];int sum[maxn];int two[maxn];void init(){ for(int i =1 ;i<maxn;i++){ f[i] = 0; two[i]=0; } for(int i=2;i<maxn;i++){ if(!f[i]){ for(int j = i;j<maxn;j+=i){ f[j] = i; } } } for(int i=2;i<maxn;i++){ if(f[i] ==0){ f[i] =1; }else{ int j = i/f[i]; if(j%f[i] ==0){ two[i] = two[j]+1; }else{ two[i] = two[j]; } f[i] = f[j]+1; } } for(int i=2;i<=maxn;i++){ if(two[i] == 1){ if(f[i]&1){ f[i] =1; }else{ f[i] = -1; } }else if(two[i] == 0){ if((f[i])&1){ }else{ f[i] = -f[i]; } }else{ f[i] = 0; } } sum[0]= 0; sum[1] = 0; for(int i=2;i<maxn;i++){ sum[i] = sum[i-1] + f[i]; }}int a,b, c;LL ans;void gcd(int a,int b){ int k = min(a,b); for(int i = k , j ; i > 1 ; i = j ){ LL ta = a/i, tb = b/i; j =max(a/ (ta+1) , b /(tb+1)); ans += (LL)ta*tb*(sum[i] - sum[j]); // cout << ta<<" "<<tb<< " "<<sum[i] - sum[j]<<endl; }} int main(){ init(); int t ; cin>>t; while(t--){ scanf("%d%d",&a,&b); ans = 0; gcd(a,b); printf("%lld\n",ans); } return 0;}
- spoj Primes in GCD Table 莫比乌斯反演
- spoj 4491. Primes in GCD Table 莫比乌斯反演
- SPOJ 4491 Primes in GCD Table(莫比乌斯反演)
- 【莫比乌斯反演】[SPOJ-PGCD]Primes in GCD Table
- SPOJ - PGCD Primes in GCD Table - 莫比乌斯反演
- 【SPOJ PGCD】Primes in GCD Table——莫比乌斯反演2
- SPOJ 4491 PGCD - Primes in GCD Table(莫比乌斯反演)
- SPOJ PGCD - Primes in GCD Table (莫比乌斯)
- SPOJ PGCD - Primes in GCD Table (好题! 莫比乌斯反演+分块求和优化)
- SPOJ PGCD - Primes in GCD Table [莫比乌斯反演+分段+求和优化]【组合数学】
- SPOJ 4491. Primes in GCD Table 【mobius反演】
- SPOJ4491 Primes in GCD Table 莫比乌斯反演+分块+前缀和
- SPOJ-PGCD Primes in GCD Table (Mobius反演 好题)
- SPOJ 4491 Primes in GCD Table
- spoj 4491 莫比乌斯反演
- BZOJ 2818 Gcd + spoj 4491(莫比乌斯反演 分块)
- HDU1695 GCD(莫比乌斯反演)
- GCD问题--莫比乌斯反演
- 程序编译运行时头文件或动态链接库的查找
- 受限的玻尔兹曼机
- 关于Android XML文件的解析方式DOM,SAX,Pull的具体实现。
- 黑马程序员——String str1="abc";String str2=new String("abc");内部原理剖析
- experiment : test CreateProcessWithLogonW
- spoj 4491. Primes in GCD Table 莫比乌斯反演
- 大型企业为何要用腾讯通RTX?甚至很多政府机关也在用RTX
- 实现文本的 复制 粘贴 的创建
- android binder机制之--(我是binder)
- 10个Android开源项目
- 了解css响应式布局的概念
- uva 147
- CoUpdate
- 关于COM组件