ural 1907 Coffee and Buns

题意:

  给定一个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任意一个因子的倍数

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

 

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 
 4 using namespace std;
 5 typedef long long LL;
 6 
 7 const int N=1100000;
 8 int pr[N],p[N/10],lp;
 9 LL fac[100],ans,num;
10 void gp(){
11     for(int i=2;i<N;i++){
12         if(!pr[i])p[lp++]=pr[i]=i;
13         for(int j=0;j<lp && i*p[j]<N;j++){
14             pr[i*p[j]]=p[j];
15             if(i%p[j]==0)break;
16         }
17     }
18 }
19 void dfs(int st,int end,int cnt,int need,LL n){
20     if(cnt==need){
21         if(cnt&1){
22             ans = ans+n;
23         }
24         else{
25             ans = ans-n;
26         }
27         return;
28     }
29     for(int i=st;i<end;i++){
30         dfs(i+1,end,cnt+1,need,n/fac[i]);
31     }
32 }
33 void getfactor(LL a){
34     num = 0;
35     for(int i=0;i<lp;i++){
36         if(p[i]>a) break;
37         if(a%p[i]==0){
38             fac[num++]=p[i];
39             while(a%p[i]==0){
40                 a/=p[i];
41             }
42         }
43     }
44     if(a!=1) fac[num++] = a;
45 }
46 int main()
47 {
48     LL a,n;
49     gp();
50     cin>>a>>n;
51     ans=0; getfactor(a);
52     if(a&1){
53         ans+=(n+1)/2;
54         for(int i=1;i<=num;i++)
55             dfs(0,num,0,i,n/2);
56         cout<<ans<<endl;
57     }
58     else{
59         for(int i=1;i<=num;i++)
60             dfs(0,num,0,i,n);
61         cout<<ans<<endl;
62     }
63     return 0;
64 }
ural 1907

 

 

posted @ 2013-11-26 22:13  破晓べ  阅读(193)  评论(0编辑  收藏  举报