GCD问题
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
给出区间 gcd(x,y) = k,a <=x <= b,c <= y <= d 。T(1 <= T <= 100).T行,每行五个整数
输出
输出
示例输入
2 384 31270 278 37299 70 336 35722 493 16985 158
示例输出
141647 14170
题目链接:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=3320
很水的一个反演,不过我很高兴,自从下定决心来干掉反演之后这是做出来的第一个反演的题,已经卡了我3天了,我此刻的心情只能用一串中文字符来表达,哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈......爽!
我的反演是看百科懂的,很神奇吧,顺着百科推一遍你就回得到f(x)和g(x)的关系了。当然,我还只是个反演小白,本质没有变化。
这是百科的链接,有感兴趣的可以去学一下,以前看不懂金桔的博客,现在发现写的还挺对,辛苦他打这么多字了,既然如此,我只好http://blog.youkuaiyun.com/a1s4z5/article/details/51333840,嘿嘿嘿嘿嘿。
讲的很好,第二部分我到现在也没有懂。。。其实说白了,莫比乌斯反演就是一个偏序集上的容斥,u(x)就是容斥系数,其实u(x)就是个欧拉函数,所以,强烈建议先去学前置技能。
1.容斥原理
2.唯一分解定理
3.欧拉函数定义
4.积性函数定义
容斥的话我是上知乎学的,哦,还有组合数学那本书,唯一分解定理也是在百科,我记得好像文库里面有篇论文,里面有唯一分解定理的应用,但是并没有看懂多少。。。毕竟渣,欧拉函数和积性函数我到现在也只是知道结论,不过对于我们来说知道结论也够了。
在这里,我一定要放上莫比乌斯反演的两种形式
形式一
如果有
f(n)=∑d|ng(d)
那么
g(n)=∑d|nμ(d)f(nd)
形式二
如果有
f(n)=∑n|dg(d)
那么
g(n)=∑n|dμ(dn)f(d)
证明的话是用卷积证明(乘法),至于必要性和充分性在百科上有,我在此就不证了,淡定!
形式一是约数关系,形式二是倍数关系。
u(x)函数的求法这里我用的是线性筛,金桔的5行板子的水平我还达不到。
http://blog.youkuaiyun.com/acdreamers/article/details/8542292
大神的板子,我看了好多博客,ACdreamr写的还不错,幻灯片也看了好多,大同小异,入了门之后初级的差不多都能看懂。网上的资料有好多,我就不在这画蛇添足了,大家想学的一搜就能搜到好多的。
对于反演,我也是刚刚入门,可能都达不到入门的水平,这篇博客我还会再修改的,这只是1.0版本,好了,罗嗦了一大堆,上代码。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int mu[60000];
int prime[600000];
int vis[600000];
int cnt;
void Init()//u(x)
{
memset(vis,0,sizeof(vis));
mu[1] = 1;
cnt = 0;
for(int i=2; i<=50000; i++)
{
if(!vis[i])
{
prime[cnt++]=i;
mu[i]=-1;
}
for(int j=0; j<cnt&&i*prime[j]<=50000; j++)
{
vis[i*prime[j]] = 1;
if(i%prime[j]) mu[i*prime[j]] = -mu[i];
else
{
mu[i*prime[j]] = 0;
break;
}
}
}
}
int k;
long long fax(int n,int m)
{
n/=k;
m/=k;
long long sum=0;
int p=min(n,m);
for(int i=1;i<=p;i++)
{
sum+=mu[i]*(n/i)*(m/i);
}
return sum;
}
int main()
{
int t;
Init();
int a,b,c,d;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
long long sum=0;
sum+=fax(b,d);
sum-=fax(a-1,d);
sum-=fax(b,c-1);
sum+=fax(a-1,c-1);//容斥原理
cout<<sum<<endl;
}
return 0;
}