这一题学到的东西
1.
unsigned int: 0~4294967295 (10位数,4e9)
int :-2147483648~2147483647 (10位数,2e9 2^31 - 1)
long long:-9223372036854775808~9223372036854775807 (19位数, 9e18 ) 2^63 - 1
unsigned long long:0~18446744073709551615 (20位数,1e19) 2^64 - 1
第一次写出来wa就wa在它的范围是到2的64,但是我只用了long long。
2.
输出的unsigned long long 时要用(“%llu”);
3.typedef和 define 都可以使用来重命名,但是命名后最好用大写,增加可读性,比如 typedef unsigned long long ULL;
4.分治法的使用,在紫书数论那里有
5.一种思想:.对一个数取m的模,最多有m的平方,由此可以得到一个数必定循环的道理。
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<iostream>
using namespace std;
typedef unsigned long long UL;
vector<UL>all[1002];
map<int,int>ser;
void make_table()
{for(int i=2;i<=1000;i++)
{
all[i].push_back(0);
all[i].push_back(1);
int a=0,b=1,c,d=2;
while(1)
{d++;
c=(a+b)%i;
a=b;b=c;
if(i==1000) printf("%d %d\n",d,c);
if(a==0&&b==1&&d!=3){ser[i]=d-2;break;}
else all[i].push_back(c);
}
}
}
int pow_mod(UL a,UL b,int m)
{ if(b==0)return 1;
int y=pow_mod(a,b/2,m)%m;
if(b%2==1)return y*y%m*a%m;
else return y*y%m;
}
int main(void)
{int t,m;
UL a,b;
make_table();
scanf("%d",&t);
while(t--)
{scanf("%llu %llu %d",&a,&b,&m);
if(a==0||m==1){printf("0\n");continue;}
if(b==0){printf("1\n");continue;}
int k=pow_mod(a%ser[m],b,ser[m]);
cout<<a<<" "<<b<<" "<<k<<" "<<m<<" "<<ser[m]<<endl;
cout<<all[m][k]<<endl;//不明白此处为什么不是输出all[m][k-1]
}
}
本题wa了3次,
第一次是没有用unsigned long long出的错误
第二次是思路错了,混乱了
第三次是我最后输出的是cout<<all[m][k-1]<<endl;但我现在仍然不知道这为什么是错的,希望dl看到了能告诉我一下。