hdu 5451 Best Solver(循环节+共轭构造)

http://acm.hdu.edu.cn/showproblem.php?pid=5451

如果指数不是那么大的话,就和那个SO EAST那道题一样的用矩阵快速幂来做

但是指数是2的2的31次方那么大,底数还是个无理数, 降幂不能

看了别人的优秀代码 ,发现是寻找循环节.因为模数很小.

对于每一个模数,都有自己的循环节.

向上取整的递推公式是 Cn=10*Cn-1 -Cn-2 

那么只要有一对连续的数重复出现,那么整个数列就都会循环起来了.所以能够找循环节.

机智啊!!!!!!!

注意写的过程中,如果感觉会发生负数取模的地方,不妨都加一个模数再来取模.

扫描二维码关注公众号,回复: 2562853 查看本文章
#include<bits/stdc++.h>
using namespace std;
long long x,mod;
long long C[55555];
long long find()
{
	C[0]=2;
	C[1]=10;
	for(long long  i=2;i<=48888;i++)
	{
		C[i]=C[i-1]*10-C[i-2];
		C[i]=(C[i]+mod)%mod;
		if(C[i]==C[1]&&C[i-1]==C[0])
		{
			return i;
		}
	}
}
long long qpow(long long a,long long cs,long long p)
{
	long long ans=1;
	while(cs)
	{
		if(cs&1)
		ans=ans*a%p;
		a=a*a%p;
		cs>>=1;
	}
	return ans;
}
long long solve()
{
	long long xhj=find();
    xhj--;
	long long zs=(1+qpow(2,x,xhj))%xhj;
	return (C[zs]-1+mod)%mod;
}
int main()
{
	int t;
	int cs=1;
	cin>>t;
    while(t--)
    {
         scanf("%lld%lld",&x,&mod);
         printf("Case #%d: %lld\n",cs++,solve());
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/threeh20/article/details/81315639