題目大意:
某生物成年的標誌是身上的所有皮膚都從不透明變成過透明至少一次,不是同時變成透明纔算。(= =!)
也就是求最裏一層皮膚變成透明的天數(最裏一層皮膚要變成透明,必須外面其他所有的皮膚都同時透明才行)。
一開始沒理解這裏,總是不明白樣例。
理解後,就可以推導了。
所以,請分清【前n層皮膚同時爲透明】和【第n層皮膚變爲透明(即前n層皮膚都變透明"過”)】
接下來用total[n]、ans[n}分別表示【前n層皮膚同時爲透明的天數】和【第n層皮膚變爲透明的天數】
(ans[n]即爲題中所求)
(舉一個有4層皮膚的pupu爲例,+表示不透明, -表示透明)
第一天 第二天 第三天 第四天 第五天 第六天 第七天 第八天 第九天
+ - + - + - + - +
+ + - - + + - - +
+ + + + - - - - +
+ + + + + + + + -
有ans[1]=total[1]=2
ans[2]=3 total[2]=4
ans[3]=5 total[3]=8
ans[4]=9
。
。
。
可以看到要使第n層皮膚變透明,必須要前n-1層同時爲透明,然後第二天第n層皮膚就會變爲透明,同時前n-1層皮膚變成不透明
即有ans[n]=total[n-1]+1----------------------------------------1
而要使前n層皮膚同時爲透明,則必須第n層皮膚變成透明,然後前n-1層同時爲透明,由於第n層皮膚變成透明的那一天,也就是前n-1層皮膚同時爲透明的過程的第一天
即有total[n]=ans[n]+total[n-1]-1---------------------------------------2
由1式代入2式可得total[n]=total[n-1]*2,又total[1]=2
所以total[n]=2^n
所以ans[n]=total[n-1]+1=2^(n-1)+1
下面是採用二分來求取高次冪
#include <cstdio>
#include <algorithm>
using namespace std;
long long pow(long long n,long long m)
{
if(!m)
return 1;
if(m==1)
return 2;
long long ans;
ans=pow(n,m/2)%n;
ans=ans*ans%n;
if(m%2==1)
ans=ans*2%n;
return ans;
}
int main()
{
long long n,ans;
while(scanf("%I64d",&n)&&n)
{
ans=(pow(n,n-1)+1)%n;
printf("%I64d\n",ans);
}
}