《算法竞赛入门经典》第十章 数学概念与方法 UVa11582(幂取模,循环规律,模算术)

来源:互联网 发布:centos开启3306端口 编辑:程序博客网 时间:2024/06/04 17:51
#include<iostream>#include<cstdio>#include<vector>#include<string>#include<cstring>#include<algorithm>#define N 1005using namespace std;typedef unsigned long long ull;ull a,b;int n;vector<int> table[N];int rem[N];//用于记录每个n所求得的循环数 ull pow_mod(ull a,ull b,int n)//快速幂取模,分治二分思想 {if(b==0) return 1;//结束条件,开始"归” ull x=pow_mod(a,b/2,n);//分治开始 ,开始"递” x=(x*x)%n;if(b%2) x=(x*a)%n;//如果是奇数的话,就额外乘一个a return x;} void make_table()//制表,以不同的n作为行数,每行记录一个循环内的全部数,并用rem数组来记录循环的长度 {for(int i=2;i<N; i++ ){    table[i].push_back(0);table[i].push_back(1);//将每一行的前两个初始化为1和0 for(int j=2;;j++){table[i].push_back((table[i][j-1]+table[i][j-2])%i);if(table[i][j]==1&&table[i][j-1]==0)//检验是否出现了循环         {  rem[i]=j-1;//记录循环的长度   break;  }}}}int main(){   //freopen("E:\\in.txt","r",stdin);    //freopen("E:\\out.txt","w",stdout);   make_table();//事先制表    int t;   cin>>t;   while(t--)   {     cin>>a>>b>>n;     if(a==0) cout<<0<<endl;     else if(rem[n]==0) cout<<0<<endl;//对两种特殊情况进行处理      else{ int ans=pow_mod(a%rem[n],b,rem[n]);//得到a^b,在一个循环中所处的位置         cout<<table[n][ans]<<endl;     }   }   return 0;} 

阅读全文
0 0
原创粉丝点击