ACM-ICPC 2015 Shenyang Preliminary Contest B. Best Solver

The so-called best problem solver can easily solve this problem, with his/her childhood sweetheart.

It is known that y=(5+2 *sqrt(6))^(1+2^x)

For a given integer x(0x<2^32) and a given prime number M(M46337), print [y]%M. ([y]means the integer part of y)

Input Format

An integer T(1<T1000), indicating there are T test cases.

Following are T lines, each containing two integers x and M, as introduced above.

Output Format

The output contains exactly T lines.

Each line contains an integer representing [y]%M.

样例输入

7
0 46337
1 46337
3 46337
1 46337
21 46337
321 46337
4321 46337

样例输出

Case #1: 97
Case #2: 969
Case #3: 16537
Case #4: 969
Case #5: 40453
Case #6: 10211
Case #7: 17947

题目来源

ACM-ICPC 2015 Shenyang Preliminary Contest

 

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <vector>
 5 #include <cmath>
 6 #include <algorithm>
 7 using namespace std;
 8 #define N 100005//一开始是10005,一直超时/
 9 #define mod 1000000007
10 #define gep(i,a,b) for(int i=a;i<=b;i++)
11 #define mem(a,b) memset(a,b,sizeof(a))
12 #define ll  long long 
13 /*
14 a(n)=(5+sqrt(6))^n,b(n)=(5-sqrt(6))^n
15 c(n)=a(n)+b(n)//是个整数
16 a(n)-(1-b(n))=a(n)+b(n)-1=c(n)-1为a(n)向下取整的结果。
17 c(n)*((5+sqrt(6))+(5-qrt(6)))
18 因此10*c(n)=c(n+1)+c(n-1)
19 c(n+1)=10*c(n)-c(n-1)
20 */
21 int t;
22 ll x,m;
23 ll c[N];
24 ll len;
25 ll  solve(){
26     c[1]=10%m;
27     c[2]=98%m;
28     //cout<<m<<endl;
29     for(int i=3;;i++)
30     {
31         c[i]=(10*c[i-1]-c[i-2]+m)%m;
32         //cout<<c[i]<<endl;
33         if(c[i-1]==c[1]&&c[i]==c[2]){
34             //cout<<len<<endl;
35             return len=i-2;
36         }
37     }
38 }
39 ll poww(ll a,ll b,ll p){
40     ll ans=1%p;
41     a%=p;
42     while(b){
43         if(b&1)  ans=(ans*a)%p;
44         b>>=1;
45         a=(a*a)%p;
46     }
47     return ans%p;
48 }
49 int main()
50 {
51     scanf("%d",&t);
52     gep(i,1,t){
53         scanf("%lld%lld",&x,&m);//1+2^x(x很大)一定有循环节。
54         //cout<<x<<" "<<m<<endl;
55         solve();//因为%m的m不大,因此每次都去找循环节。
56         ll id=poww(2,x,len);
57         id=(id+1)%len;
58         printf("Case #%d: %lld
",i,((c[id]-1)%m+m)%m);
59     }
60     return 0;
61 }
原文地址:https://www.cnblogs.com/tingtin/p/9420737.html