天天看點

反正切函數的應用

Description

反正切函數可展開成無窮級數,有如下公式 

反正切函數的應用

(其中0 <= x <= 1) 公式(1) 

使用反正切函數計算PI是一種常用的方法。例如,最簡單的計算PI的方法: 

PI=4arctan(1)=4(1-1/3+1/5-1/7+1/9-1/11+...) 公式(2) 

然而,這種方法的效率很低,但我們可以根據角度和的正切函數公式: 

tan(a+b)=[tan(a)+tan(b)]/[1-tan(a)*tan(b)] 公式(3) 

通過簡單的變換得到: 

arctan(p)+arctan(q)=arctan[(p+q)/(1-pq)] 公式(4) 

利用這個公式,令p=1/2,q=1/3,則(p+q)/(1-pq)=1,有 

arctan(1/2)+arctan(1/3)=arctan[(1/2+1/3)/(1-1/2*1/3)]=arctan(1) 

使用1/2和1/3的反正切來計算arctan(1),速度就快多了。 

我們将公式(4)寫成如下形式 

arctan(1/a)=arctan(1/b)+arctan(1/c) 

其中a,b和c均為正整數。 

我們的問題是:對于每一個給定的a(1 <= a <= 60000),求b+c的值。我們保證對于任意的a都存在整數解。如果有多個解,要求你給出b+c最小的解。 

Input

輸入檔案中隻有一個正整數a,其中 1 <= a <= 60000。

Output

輸出檔案中隻有一個整數,為 b+c 的值。

Sample Input

1      

Sample Output

5      

題目要求求出

1 / a = (1 / b+1 / c) / (1 - 1 / (b * c) )

==> ab + ac = bc - 1

令b=a+m, c=a+n

==> mn=a^2+1

是以m或n必然小于a,且為正整數

是以可以直接枚舉m的值了,注意計算a*a可能爆int改用long long;

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <cstdio>
#include <cmath>
#include <string>
#include <stack>
#include <cctype>
using namespace std;

int main()
{
    //freopen("tangs.txt","w",stdout);
    int a;
     while(~scanf("%d",&a))
    {
            for(int i=a; i>=1; i--)
                if(((long long)(a)*a+1)%i==0)
                {
                    printf("%I64d\n",a+i+a+((long long)(a)*a+1)/i);
                    break;
                }

        }
         return 0;
    }