CH Round#54 免农

来源:互联网 发布:iphone7怎么信任软件 编辑:程序博客网 时间:2024/05/16 02:03

免农

萌蛋近年收入不景气,正在她发愁如何能多赚点钱时,她听到隔壁的小朋友在讨论免子繁殖的问题。(注:免子是一种简单的单细胞生物)

问题是这样的:时刻 02只刚出生的免子。每一时刻,每只免子都会分裂成为2 只免子。问时刻n 共有多少只免子?聪明的你可能已经发现,时刻n 的免子数正好是第n+1 2 的幂次。萌蛋不懂什么叫幂,但她也发现了规律:时刻n+1 的免子数等于时刻n的免子数的 2倍。前几个时刻(从 0开始)的免子数依次为:

2 4 8 16 32 64 128 256 512 ...

萌蛋发现越到后面免子数增长的越快,期待养免子一定能赚大钱,于是萌蛋在时刻0 买了2 只免子开始培养。每天,萌蛋都要给免子们提供营养。免子的培养基非常特别,每k 只免子占据一个培养基,最后剩下的不足k 只占据一个培养基。由于免子特别害怕孤独,如果某个培养基只有1 只免子,这只免子就会很快死掉。

然而,每个时刻的免子数仍然是可以计算的。例如,当k=7 时,前几个时刻(从0 开始)的免子数依次为:
2 4 7 14 28 56 112 224 448 ...

给定 n,你能帮助萌蛋计算时刻n 她有多少只免子么?由于答案可能非常大,你只需要告诉萌蛋时刻n 的免子只数对p 的余数即

可。

【输入格式】

输入只有一行,包含三个整数 n k p【输出格式】

输出只有一行,为一个整数,表示时刻 n 的免子只数对p 的余数。

【样例输入】

6 7 10086

【样例输出】

112

【数据范围】

对于 30%的数据,n1,000,000
另有
30%的数据,kp的正整数倍。
对于
100%的数据,n1,000,000,000,2k1,000,000,1p

1,000,000。 




    首先,如果k是偶数,一定不会有免子死亡,那么只需求一次快速幂,并在每一步对p取模。

其次,如果k是奇数,那么2与k互质,由欧拉定理,得2^phi(p)=1(mod p),所以最多只需phi(p)天,将会有免子死亡。因为p的范围并不大,所以我们可以暴力枚举出是哪一天有免子死亡,从这天开始将不会有免子死亡。所以将n天分成两部分,分别求快速幂,记作u和v,最后答案即为(u-1)*v mod p。






#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define F(i,j,n) for(int i=j;i<=n;i++)#define D(i,j,n) for(int i=j;i>=n;i--)#define LL long longusing namespace std;int n,k,p,y,tmp;void solve(){int x=2,ans=1;for(;n;n>>=1){if (n&1) ans=(LL)ans*x%p;x=(LL)x*x%p;}printf("%d\n",ans);}int main(){scanf("%d%d%d",&n,&k,&p);n++;if (k%2==0){solve();return 0;}y=2;tmp=1;while (y%k!=1&&tmp<=n){y=(LL)y*2%k;tmp++;}if (tmp>n){solve();return 0;}int z=n-tmp,u=1,x=2,v=1,ans;for(;tmp;tmp>>=1){if (tmp&1) u=(LL)u*x%p;x=(LL)x*x%p;}x=2;for(;z;z>>=1){if (z&1) v=(LL)v*x%p;x=(LL)x*x%p;}u=(u-1+p)%p;ans=(LL)u*v%p;printf("%d\n",ans);}








0 0
原创粉丝点击