hdu 4746 Mophues 莫比乌斯 分块优化
来源:互联网 发布:网络追逃能坐火车吗 编辑:程序博客网 时间:2024/06/05 20:11
Description
As we know, any positive integer C ( C >= 2 ) can be written as the multiply of some prime numbers:
C = p1×p2× p3× ... × pk
which p1, p2 ... pk are all prime numbers.For example, if C = 24, then:
24 = 2 × 2 × 2 × 3
here, p1 = p2 = p3 = 2, p4 = 3, k = 4
Given two integers P and C. if k<=P( k is the number of C's prime factors), we call C a lucky number of P.
Now, XXX needs to count the number of pairs (a, b), which 1<=a<=n , 1<=b<=m, and gcd(a,b) is a lucky number of a given P ( "gcd" means "greatest common divisor").
Please note that we define 1 as lucky number of any non-negative integers because 1 has no prime factor.
Input
The first line of input is an integer Q meaning that there are Q test cases.
Then Q lines follow, each line is a test case and each test case contains three non-negative numbers: n, m and P (n, m, P <= 5×10 5. Q <=5000).
Output
For each test case, print the number of pairs (a, b), which 1<=a<=n , 1<=b<=m, and gcd(a,b) is a lucky number of P.
Sample Input
210 10 010 10 1
Sample Output
6393
然后由莫比乌斯反演,我们知道f(d)=g(d)*u(1)+g(2*d)*u(2)+g(3*d)*u(3)+....
考虑结果ans,ans为所有f(d)且F(d)<=P的和,
我们枚举1<=i<=n,如果i是某个d的倍数且F(d)<=P,那么ans+=g(i)*u(i/d)=[n/i]*[m/i]*u(i/d)。那么这个怎么计算能更快一点?
我们设G(i)为容斥因子:G(i)=sum{u(i/d) | F(d)<=P} 这个值可以nlogn预处理出来,然后我们只需要ans+=G(i)*[n/i]*[m/i]即可
这样的话总的复杂度为O(n*q)还是会T的样子
然后我们注意到[n/i]*[m/i]在一定的范围内是不变的,这个范围是[i,min(n/(n/i),m/(m/i)],这样我们可以预处理出G(i)的前缀和,然后加快运算(复杂度网上说是sqrt(n)的。。。)
这样总的复杂度是O(q*sqrt(n)+nlog(n))大概这样.
#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>#include<cstring>#include<vector>#include<set>#include<map>#include<queue>#include<bitset>#define fi first#define se second#define pii pair<int,int>#define ll long long#define inf 1<<30#define eps 1e-8using namespace std;const int maxn=500010;int num[maxn];int cnt[19][maxn];int n,m,p;int mu[maxn],prime[maxn],tot;bool check[maxn];void getmu(){ int N=500000; memset(check,0,sizeof(check)); mu[1]=1,tot=0; for(int i=2;i<=N;i++){ if(!check[i]) prime[tot++]=i,mu[i]=-1; for(int j=0;j<tot;j++){ if(i*prime[j]>N) break; check[i*prime[j]]=true; if(i%prime[j]==0){ mu[i*prime[j]]=0; break; } else mu[i*prime[j]]=-mu[i]; } } for(int i=1;i<=N;i++) { int u=i; int v=0; for(int j=0;j<tot;j++) { if(prime[j]*prime[j]>u) break; while(u%prime[j]==0) { u/=prime[j]; v++; } } if(u>1) v++; num[i]=v; }}void init(){ memset(cnt,0,sizeof(num)); int N=500000; for(int i=1;i<=N;i++) { for(int j=i;j<=N;j+=i) { cnt[num[i]][j]+=mu[j/i]; } } for(int i=1;i<=N;i++) { for(int j=1;j<=18;j++) { cnt[j][i]+=cnt[j-1][i]; } } for(int i=0;i<=18;i++) { for(int j=1;j<=N;j++) { cnt[i][j]+=cnt[i][j-1]; } }}int main(){ getmu(); init(); int t; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&p); if(p>18) { printf("%I64d\n",(ll)n*m); continue; } ll ans=0; if(n>m) swap(n,m); for(int i=1;i<=n;) { int j=min(n/(n/i),m/(m/i)); //cout<<i<<" "<<j<<endl; ans+=(ll)(cnt[p][j]-cnt[p][i-1])*(n/i)*(m/i); i=j+1; } printf("%I64d\n",ans); } return 0;}
- hdu 4746 Mophues 莫比乌斯 分块优化
- hdu 4746 Mophues (莫比乌斯反演 + 分块+线性筛)
- hdu 4746 Mophues 莫比乌斯反演
- HDU 4746 Mophues 莫比乌斯第三弹
- HDU 4746 Mophues (莫比乌斯反演应用)
- HDU 4746 Mophues(莫比乌斯反演)
- HDU 4746 Mophues(莫比乌斯反演)
- HDU 4746 Mophues【莫比乌斯反演】
- HDU 4746 Mophues (莫比乌斯反演应用)
- HDU 4746-Mophues (莫比乌斯反演)
- HDU 4746 Mophues(有趣的前缀和/莫比乌斯反演)
- HDU4746 Mophues(莫比乌斯反演)
- hdu4746 Mophues(莫比乌斯反演)-好题
- HYSBZ 2301 Problem b 莫比乌斯 分块优化
- bzoj 2301 -莫比乌斯函数反演+分块优化
- [BZOJ]1101 莫比乌斯+分块优化
- HDU 6053 TrickGCD(莫比乌斯反演+分块)
- hdu 4746 Mophues
- HTML基础_01_基础标签
- c语言 常量
- 九度OJ 1139:最大子矩阵 (矩阵运算、缓存)
- cf 55c Pie or die
- __attribute_used__的作用
- hdu 4746 Mophues 莫比乌斯 分块优化
- g711u g711a 格式相互转换
- cf 75c Modified GCD
- C/C++面试(3)——矩阵编程题(模拟法)
- hdoj 4347 KD树
- 数理统计总结
- 模糊与精确
- Sql 数据库的新建,表的新建,约束操作,简单查询
- 杭电1871 无题