您的位置:首页 > Web前端

ural 1907 Coffee and Buns

2013-11-26 22:13 260 查看
题意:

  给定一个a和n,求在1-n之间有几个数x,满足gcd(4(a+x),a^2+x^2)>1

思路:

  比赛的时候打表看出了规律,结果容斥都写错了,囧!

  赛后看了佳哥和尧神的思路,我想问自己智商在哪!!T^T

  gcd(4(a+x),a^2+x^2)>1 ----> gcd(a+x,(a+x)^2-2ax)>1 (4是无关紧要的,如果没有4的时候不成立,加上4也不成立) ----> gcd(a+x,2ax)>1 (gcd(a,b)=gcd(b,a%b)

假设a是偶数,那么gcd(a+x,2ax)>1 ----> gcd(a+x,ax)

  设最大公约数为g,则g|ax,g|a+x

  如果g|a,那么g|x,如果g|x,那么g|a,所以只要x是a任意一个因子的倍数就合法

  假设a是奇数,那么有2种情况

  1.x是奇数

  2.x是a任意一个因子的倍数

  正好和打表的规律一样,哈哈,好有趣~~

代码:

#include <iostream>
#include <cstdio>

using namespace std;
typedef long long LL;

const int N=1100000;
int pr
,p[N/10],lp;
LL fac[100],ans,num;
void gp(){
for(int i=2;i<N;i++){
if(!pr[i])p[lp++]=pr[i]=i;
for(int j=0;j<lp && i*p[j]<N;j++){
pr[i*p[j]]=p[j];
if(i%p[j]==0)break;
}
}
}
void dfs(int st,int end,int cnt,int need,LL n){
if(cnt==need){
if(cnt&1){
ans = ans+n;
}
else{
ans = ans-n;
}
return;
}
for(int i=st;i<end;i++){
dfs(i+1,end,cnt+1,need,n/fac[i]);
}
}
void getfactor(LL a){
num = 0;
for(int i=0;i<lp;i++){
if(p[i]>a) break;
if(a%p[i]==0){
fac[num++]=p[i];
while(a%p[i]==0){
a/=p[i];
}
}
}
if(a!=1) fac[num++] = a;
}
int main()
{
LL a,n;
gp();
cin>>a>>n;
ans=0; getfactor(a);
if(a&1){
ans+=(n+1)/2;
for(int i=1;i<=num;i++)
dfs(0,num,0,i,n/2);
cout<<ans<<endl;
}
else{
for(int i=1;i<=num;i++)
dfs(0,num,0,i,n);
cout<<ans<<endl;
}
return 0;
}


ural 1907
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: