码迷,mamicode.com
首页 > 其他好文 > 详细

【Foreign】无聊的计算姬 [Lucas][BSGS]

时间:2017-03-16 19:01:14      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:png   cstring   rip   splay   amp   desc   sof   block   mil   

无聊的计算姬

Time Limit: 10 Sec  Memory Limit: 256 MB

Description

  技术分享

Input

  技术分享

Output

  技术分享

Sample Input

  6
  2 2 3 4
  3 2 7 9
  2 1 2 9
  3 1 6 7
  1 5 3 7
  1 9 2 8

Sample Output

  Math Error
  3
  Math Error
  6
  6
  1

HINT

  技术分享

Source

  我们可以分步骗分。(Task1直接快速幂即可。)  

  对于前50分:

    对于Task2,我们直接暴力枚举,出现一个重复的停止,判断是否存在即可,对于Task3,直接n^2递推组合数即可。

  对于11~16的20分:

    对于Task2,我们运用BSGS求解即可,对于Task3,直接上Lucas即可。

Code

技术分享
  1 #include<iostream>  
  2 #include<string>  
  3 #include<algorithm>  
  4 #include<cstdio>  
  5 #include<cstring>  
  6 #include<cstdlib>  
  7 #include<cmath>  
  8 #include<map>
  9 using namespace std;  
 10 typedef long long s64;
 11 
 12 const int ONE = 10000005;
 13 
 14 map <int,int> f;
 15 
 16 int T;
 17 int type,y,z,MOD;
 18 int Jc[ONE];
 19 int C[1005][1005];
 20 
 21 int get() 
 22 {
 23         int res=1,Q=1;  char c;
 24         while( (c=getchar())<48 || c>57)
 25         if(c==-)Q=-1;
 26         if(Q) res=c-48; 
 27         while((c=getchar())>=48 && c<=57) 
 28         res=res*10+c-48; 
 29         return res*Q; 
 30 }
 31 
 32 int Quickpow(int a,int b,int MOD)
 33 {
 34         int res=1;
 35         while(b)
 36         {
 37             if(b&1) res=(s64)res*a%MOD;
 38             a=(s64)a*a%MOD;
 39             b>>=1;
 40         }
 41         return res;
 42 }
 43 
 44 namespace PC
 45 {
 46         int Make_C(int a,int b,int MOD)
 47         {
 48             C[0][0]=1;
 49             for(int i=1;i<=a;i++)
 50             {
 51                 C[i][0]=1;
 52                 for(int j=1;j<=b;j++)
 53                 C[i][j] = (C[i-1][j]+C[i-1][j-1]) % MOD;
 54             }
 55             return C[a][b];
 56         }
 57         
 58         int C(int n,int m,int MOD)
 59         {
 60             int up = Jc[n];
 61             int down = (s64)Jc[m] * Jc[n-m] % MOD;    
 62             return (s64)up * Quickpow(down,MOD-2,MOD) % MOD;
 63         }
 64         
 65         int Lucas(int n,int m,int MOD)
 66         {
 67             Jc[0]=1;
 68             for(int i=1;i<=MOD;i++) Jc[i] = (s64)Jc[i-1] * i % MOD;
 69             int res = 1;
 70             while(n && m)
 71             {
 72                 res = (s64)res * C(n%MOD,m%MOD,MOD) % MOD;
 73                 n/=MOD;    m/=MOD;
 74             }
 75             return res;
 76         }    
 77 }
 78 
 79 namespace PB
 80 {
 81         int Make_min(int a,int b,int MOD)
 82         {
 83             int res=1;
 84             if(res==b) return 0;
 85             f.clear();
 86             for(int i=1;i<=100000;i++)
 87             {
 88                 res = (s64)res * a % MOD;
 89                 if(f[res]) return -1;
 90                 f[res] = 1;
 91                 if(res==b) return i;
 92             }
 93             return -1;
 94         }
 95         
 96         int BSGS(int A,int B,int MOD)
 97         {
 98             if(A % MOD == 0) return -1;
 99             int m = sqrt(MOD) + 1;
100             f.clear();
101             int record = B % MOD;
102             for(int i=1;i<=m;i++)
103             {
104                 record = (s64) record * A % MOD;
105                 f[record] = i; 
106             }
107             
108             int A_m = Quickpow(A,m,MOD);
109             record = 1;
110             for(int i=1;i<=m;i++)
111             {
112                 record = (s64)record * A_m % MOD; 
113                 if(f[record])
114                 {
115                     int x = (i * m %MOD- f[record]+MOD) %MOD;
116                     return x;
117                 }
118             }
119             return -1;
120         }
121 }
122 
123 int main()  
124 {      
125         T=get();
126         while(T--)
127         {
128             type=get();
129             y=get();    z=get();    MOD=get();
130             if(type==1) printf("%d\n",Quickpow(y,z,MOD));
131             if(type==3) 
132             {
133                 if(z<=1000 && y<=1000)
134                     printf("%d\n",PC::Make_C(z,y,MOD));    
135                 else
136                     printf("%d\n",PC::Lucas(z,y,MOD));
137             }
138             if(type==2)
139             {
140                 if(z<=1000 && y<=1000)
141                 {
142                     int res=PB::Make_min(y,z,MOD);
143                     if(res==-1) printf("Math Error\n");
144                     else printf("%d\n",res);
145                 }
146                 else
147                 {
148                     int res=PB::BSGS(y,z,MOD);
149                     if(res==-1) printf("Math Error\n");
150                     else printf("%d\n",res);
151                 }
152             }
153         }    
154 }
View Code

 

【Foreign】无聊的计算姬 [Lucas][BSGS]

标签:png   cstring   rip   splay   amp   desc   sof   block   mil   

原文地址:http://www.cnblogs.com/BearChild/p/6560683.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!