传送门:
http://acm.hdu.edu.cn/showproblem.php?pid=5597
打表找规律的题,因为方法比较经典,所以这里记录一下!!!!
由打表找规律得f(x)=x+1
则fn(x)=x+n+1
因此套个欧拉函数的板子就可以了!!!!
要注意一下欧拉函数的写法,刚开始还是想错了,确实是根号n的复杂度就可以了,把n质因数分解了,写成那个质因数的表达形式,然后遇到一个质因数,一直除到底,直到除不尽了最后判断一下就ok了!!!且一定能保证最后剩下的那个数是质数,否则若是某个数的平方的话,就一定能继续除下去!!跳不出那个循环!!!
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll eular(ll n){
ll res=n;ll a=n;
for(ll i=2;i*i<=a;i++){
if(a%i==0) res=res/i*(i-1);
while(a%i==0) a/=i;
}
if(a>1) res=res/a*(a-1);
return res;
}
ll n,m;
int main(){
while(scanf("%lld%lld",&n,&m)!=EOF){
printf("%lld\n",eular(n+m+1));
}
return 0;
}
注意在写组合函数初始化的时候一定要把所有的c[i][0]都置为1,因为在计算
c[i][1]的时候等于c[i-1][0]+c[i-1][1],
c[n][m]=c[n-1][m]+c[n-1][m-1]
含义为从n个里面取m个,分为第n个取还是不取两种情况!!!!
思维也要定式一下,只要看到了-1,那么就一定要考虑边界初始化的问题!!!
所以一定把它初始化了!!!
找规律:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int c[105][105];
ll euler(ll n){
ll res=n,a=n;
for(ll i=2;i*i<=a;i++){
if(a%i==0){
res=res/i*(i-1);
while(a%i==0) a/=i;
}
}
if(a>1) res=res/a*(a-1);
return res;
}
void init()
{
for(int i=0;i<=100;i++)
{
c[i][0]=1;
}
for(int i=1;i<=100;i++)
{
for(int j=1;j<=i;j++)
{
c[i][j]=c[i-1][j-1]+c[i-1][j];
}
}
}
int a[105];
int main()
{
//cout<<(pow(2,3))<<endl;
/*init();int sum=0;int tmp=1;int x=3;
//printf("%d\n",c[5][2]);
for(int i=0;i<=20;i++)
{
if(i>0) x=a[i-1];tmp=1;sum=0;
for(int k=0;k<=x;k++)
{
tmp=tmp*c[2*x-k+1][k]*(int)pow(2,2*x-2*k);
if(k%2==1) tmp=0-tmp;
sum+=tmp;
tmp=1;
}
a[i]=sum;
}
for(int i=0;i<=20;i++)
{
cout<<"i="<<i<<" "<<"a[i]="<<a[i]<<endl;
}*///f(x)=x+1+n;
ll n,x;
while(scanf("%lld%lld",&n,&x)!=EOF)
{
printf("%lld\n",euler(x+1+n));
}
return 0;
}