hdu1420

/*
分析:
    不懂什么降幂法,0MS滴~
不知道怎么用memset只将前c个元素置零,要不会更快。
说下我的思路吧。


    思路:
   打个hash,范围是0到c-1,然后进行小于b次的“temp*a,temp%=c”循环
运算(初始时有a%=c,temp=a),将每次算出的值置为hash[temp]=1。如果在这
之前该处hash已经被置为1了,那么break跳出循环,因为出现循环节了。然
后计算循环节长度,然后就……略~
   如果没有出现循环节,就无奈的元算b次,算出最后的结果。


    因为最多计算出c个不同的数,而且事实上,对于99.9%的情况要不了c次运算
甚至远小于c的运算次数,就会出现循环节的。所以方法可行。
    至于剩下的0.01%的概略是否存在……哪个好心人数论学得好帮我算算吧%>_<%


                                                             2012-05-02
*/



#include"stdio.h"
#include"string.h"
int hash[1000111];
int main()
{
	__int64 a,b,c;
	__int64 temp0,temp;
	__int64 flag;
	int i;
	int T;
	int head,tail,len;
	scanf("%d",&T);
	while(T--)
	{
		memset(hash,0,sizeof(hash));
		scanf("%I64d%I64d%I64d",&a,&b,&c);
		a%=c;

		hash[a]=1;
		for(i=2,temp=a;i<=b;i++)
		{
			temp*=a;
			temp%=c;
			if(hash[temp]==1)	break;
			hash[temp]=1;
		}
		tail=i;

		if(i>=b)
		{
			printf("%I64d\n",temp);
			continue;
		}
		flag=temp;
		for(i=1,temp=a;i<=b;i++)
		{
			if(temp==flag)	break;
			temp*=a;
			temp%=c;
		}
		head=i;
		len=tail-head;

		temp0=b;
		temp0-=head;
		temp0%=len;
		temp0+=head;
		for(i=2,temp=a;i<=temp0;i++)
		{
			temp*=a;
			temp%=c;
		}
		printf("%I64d\n",temp);
	}
	return 0;
}


你可能感兴趣的:(hdu1420)