题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3003
Pupu
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1747 Accepted Submission(s): 688
But there is a question, when does an infant PuPu become an adult PuPu?
Aha, we already said, PuPu is a special animal. There are several skins wraping PuPu's body, and PuPu's skins are special also, they have two states, clarity and opacity. The opacity skin will become clarity skin if it absorbs sunlight a whole day, and sunshine can pass through the clarity skin and shine the inside skin; The clarity skin will become opacity, if it absorbs sunlight a whole day, and opacity skin will keep sunshine out.
when an infant PuPu was born, all of its skins were opacity, and since the day that all of a PuPu's skins has been changed from opacity to clarity, PuPu is an adult PuPu.
For example, a PuPu who has only 3 skins will become an adult PuPu after it born 5 days(What a pity! The little guy will sustain the pressure from life only 5 days old)
Now give you the number of skins belongs to a new-laid PuPu, tell me how many days later it will become an adult PuPu?
某生物成年的标志是身上的所有皮肤都从不透明变成过透明至少一次,不是同时变成透明才算。(= =!)
也就是求最里一层皮肤变成透明的天数(最里一层皮肤要变成透明,必须外面其他所有的皮肤都同时透明才行)。
一开始没理解这里,总是不明白样例。
理解后,就可以推导了。
所以,请分清【前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
下面是采用二分来求取高次幂
1 //计算(2^(n-1)+1)%n 2 //快速幂 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 #define ll long long 7 ll multi(ll a,ll n,ll m)//¼ÆËãa^n%m 8 { 9 ll ans = 1; 10 while(n>0){ 11 if(n&1) ans = (ans*a)%m; 12 a = (a*a)%m; 13 n>>=1; 14 } 15 return ans; 16 } 17 int main() 18 { 19 ll n; 20 while(~scanf("%lld",&n)&&n) 21 { 22 printf("%lld ",(multi((ll)2,n-1,n)+1)%n); 23 } 24 return 0; 25 }