/*
分析:
不懂什么降幂法,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
*/
分析:
不懂什么降幂法,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;
}