题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695

题目解析:

Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k.

题目又说a==c==1,所以就是求[1,b]与[1,d]中gcd等于k的个数,因为若gcd(x,y)==z,那么gcd(x/z,y/z)==1,又因为不是z的倍数的肯定不是,所以不是z的倍数的可以直接去掉,所以只要将b和d除以k,然后就转化成了求两个范围中互质的对数了。即求[1,b/k],与[1,d/k]中互质的数目,让b<d,又因为 (x=5, y=7) and (x=7, y=5) are considered to be the same.

所以先求[1,b/k]中互质的数目,即phi[1]+phi[2]+phi[3].....+phi[b/k](其中phi[i]为i的欧拉函数值),再从区间[b/k+1,d/k]枚举与区间[1,b/k]中互质的数目。其中求与区间[1,b/k]中互质的数目可以通过容斥原理求得与区间[1,b/k]中不互质的数目,相减便可以求得结果。这题折腾了一中午,一直TLE,代码在后面贴了,之后看大神的博客知道了哪里超时的原因,每个数的质因子可以在打表求欧拉函数的时候顺便求出来,一种哈希的思想,这样就不用在枚举的时候每一个数在求一遍他的质因子了,好题!

代码如下:(608ms)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <math.h>
using namespace std;
typedef __int64 ll;
ll sum,phi[];
int cnt[][],f[],a,b,c,d,x;
void init()
{
memset(f,,sizeof(f));
for(int i=; i<=; i++)
{
phi[i]=;
f[i]=;
}
phi[]=;
for(int i=; i<=; i++)
{
if(!phi[i])
{
for(ll j=i; j<=; j+=i)
{
if(!phi[j]) phi[j]=j;
phi[j]=phi[j]/i*(i-);
cnt[j][f[j]++]=i;//算是哈希吧,很精辟啊,这种写法要学习
}
}
phi[i]+=phi[i-];
}
}
ll gcd(ll A,ll B)
{
return B==?A:gcd(B,A%B);
}
void dfs(ll now,ll num,ll lcm,ll &coun,int key)
{
lcm=cnt[key][now]/gcd(cnt[key][now],lcm)*lcm;
if(num&)
{
coun+=b/lcm;
}
else
{
coun-=b/lcm;
}
for(ll i=now+; i<f[key]; i++)
dfs(i,num+,lcm,coun,key);
}
int main()
{
int T,K=;
init();
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d%d",&a,&b,&c,&d,&x);
if(x == || x > b || x > d)
{
printf("Case %d: 0\n",++K);
continue;
}
b/=x;
d/=x;
sum=;
if(b>d) swap(b,d);
sum+=phi[b];
for(int i=b+; i<=d; i++)
{
ll coun=;
for(int j=; j<f[i]; j++)
{
dfs(j,,cnt[i][j],coun,i);
}
sum+=(b-coun);
}
printf("Case %d: %I64d\n",++K,sum);
}
return ;
}

TLE的:(TLE了一中午 3000ms++)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <math.h>
using namespace std;
typedef __int64 ll;
ll a,b,c,d,x,sum,top,cnt[],we;//********
int phi[],su[],prime[];
void init()
{
we=;
prime[we++]=;
su[]=su[]=;
su[]=;
for(int i=; i<; i++)
if(i%==) su[i]=;
else su[i]=;
double t=sqrt(*1.0);
for(ll i=; i<=t; i++)
{
if(su[i])
{
for(ll j=i*i; j<; j=j+i)
{
su[j]=;
}
}
}
for(ll i=; i<=; i++)
{
if(su[i]) prime[we++]=i;
}
memset(phi,,sizeof(phi));
phi[]=;
for(ll i=; i<=; i++)
{
if(!phi[i])
{
for(ll j=i; j<=; j+=i)
{
if(!phi[j]) phi[j]=j;
phi[j]=phi[j]/i*(i-);
}
}
}
}
ll gcd(ll A,ll B)
{
return B==?A:gcd(B,A%B);
}
void dfs(ll now,ll num,ll lcm,ll &coun)
{
lcm=cnt[now]/gcd(cnt[now],lcm)*lcm;
if(num&)
{
coun+=b/lcm;
//printf("hsum======%I64d\n",sum);
}
else
{
coun-=b/lcm;
}
for(ll i=now+; i<top; i++)
dfs(i,num+,lcm,coun);
}
void cal(ll key,ll &coun)
{
top=;
ll KK=;
for(ll i=prime[]; i<=key; i=prime[++KK])
{
if(key%i==)
{
cnt[top++]=i;
key/=i;
while(key%i==)
key/=i;
}
}
if(key!=)
{
cnt[top++]=key;
}
for(ll i=; i<top; i++)
{
dfs(i,,cnt[i],coun);
}
}
int main()
{
int T,K=;
init();
scanf("%d",&T);
while(T--)
{
scanf("%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&x);
if(x == || x > b || x > d)
{
printf("Case %d: 0\n",++K);
continue;
} b/=x;
d/=x;
sum=;
if(b>d) swap(b,d);
//cout<<"b=="<<b<<" "<<"d=="<<d<<endl;
for(int i=; i<=b; i++)
{
sum+=phi[i];
}
//cout<<"sumsss=="<<sum<<endl;
for(ll i=b+; i<=d; i++)
{
if(su[i])
{
sum+=b;
continue;
}
ll coun=;
cal(i,coun);
sum+=(b-coun);
}
printf("Case %d: %I64d\n",++K,sum);
}
return ;
}

HDU1695:GCD(容斥原理+欧拉函数+质因数分解)好题的更多相关文章

  1. T^TOJ - 1251 - 。◕‿◕。TMD - 欧拉函数 - 质因数分解

    http://www.fjutacm.com/Problem.jsp?pid=1251 想了很久,一开始居然还直接枚举因子d,计算重复了. 首先你要找与n的最大公因子大于m的x的个数. \[\sum\ ...

  2. HDU1695 GCD (欧拉函数+容斥原理)

    F - GCD Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  3. HDU 1695 GCD (容斥原理+欧拉函数)

    题目链接 题意 : 从[a,b]中找一个x,[c,d]中找一个y,要求GCD(x,y)= k.求满足这样条件的(x,y)的对数.(3,5)和(5,3)视为一组样例 . 思路 :要求满足GCD(x,y) ...

  4. HDU 1695 GCD(欧拉函数+容斥原理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意:x位于区间[a, b],y位于区间[c, d],求满足GCD(x, y) = k的(x, ...

  5. hdu 1695 GCD (欧拉函数、容斥原理)

    GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  6. HDU 1695 GCD (欧拉函数+容斥原理)

    GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  7. hdu 1695 GCD(欧拉函数+容斥)

    Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD( ...

  8. HDU2588:GCD(欧拉函数的应用)

    题目链接:传送门 题目需求:Given integers N and M, how many integer X satisfies 1<=X<=N and (X,N)>=M.(2& ...

  9. hdu2588 GCD (欧拉函数)

    GCD 题意:输入N,M(2<=N<=1000000000, 1<=M<=N), 设1<=X<=N,求使gcd(X,N)>=M的X的个数.  (文末有题) 知 ...

随机推荐

  1. Windows之Xmanager连接linux打开Oracle视图操作

    前提:安装Xmanager 能够百度Xmanager下载其破解版或者带注冊机的版本号,也能够官网下载.只是须要秘钥(建议下载企业版) 官网下载地址:http://www.netsarang.com/d ...

  2. 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第四节:3D公告板

    <使用Cocos2d-x 开发3D游戏>系列在线课程 第四节:3D公告板 视频地址:http://edu.csdn.net/course/attend/1330/20804 交流论坛:mo ...

  3. 第五篇:浅谈CPU 并行编程和 GPU 并行编程的区别

    前言 CPU 的并行编程技术,也是高性能计算中的热点,也是今后要努力学习的方向.那么它和 GPU 并行编程有何区别呢? 本文将做出详细的对比,分析各自的特点,为将来深入学习 CPU 并行编程技术打下铺 ...

  4. CSDN专栏收集

     Android集 1.Himi李华明的<Android游戏开发专栏>http://blog.csdn.net/column/details/androidgame.html2.老罗的&l ...

  5. Sencha中Element的使用

    在sencha touch中如果你要是用模板来构造一些UI,那么你就必定要去操作Element,如下是我对Element的一些操作和遇到的问题 获取Elenent Ext.get("ID&q ...

  6. crossdomain.xml跨域配置文件的安全注意事项

    零.绪论: 对WEB中的FLASH确实了解不多,对程序中的跨域配置也了解不多,这是自己以前写的一篇笔记,到现在也还了解不深,勉强记下来罢了,备忘. 一.什么是crossdomain.xml?这是一个f ...

  7. Promise、async、await在Egret的简单应用

    Egret Engnie 5.1.10 Egret Wing 4.1.5 一.Promise.async.await相关知识 Promise介绍 阮一峰 async函数 阮一峰 具体和详细的说明用法可 ...

  8. 证书:数字签名和验签&加密和解密

    用的是湖北省数字证书认证管理中心的签名和加密 1.带私钥的证书,即p12格式证书(后缀为.pfx) 2.不带私钥的证书,有多种格式,通常我们使用的是cer格式证书(后缀为.cer) 一. 1.什么是对 ...

  9. java反射(一)

    在JDK中,主要由以下类实现java反射机制:Class类:代表一个类,Filed类:代表类的成员变量,Method类:代表类的方法,Constructor类:代表类的构造方法,Array类:提供平了 ...

  10. 香港主机Squid+Stunnel代理搭建

    1.说明 Squid,代理软件 Stunnel,数据包加密(貌似如果数据不加密,客户端的数据流无法传到squid服务端,原因你懂的!) 2.Squid安装略 3.安装完squid后需要以下操作 a.生 ...