zoukankan      html  css  js  c++  java
  • 【POJ3243】【拓展BSGS】Clever Y

    Description

    Little Y finds there is a very interesting formula in mathematics:

    XY mod Z = K

    Given X, Y, Z, we all know how to figure out K fast. However, given X, Z, K, could you figure out Y fast?

    Input

    Input data consists of no more than 20 test cases. For each test case, there would be only one line containing 3 integers X, Z, K (0 ≤ X, Z, K ≤ 109).
    Input file ends with 3 zeros separated by spaces.

    Output

    For each test case output one line. Write "No Solution" (without quotes) if you cannot find a feasible Y (0 ≤ Y < Z). Otherwise output the minimum Y you find.

    Sample Input

    5 58 33
    2 4 3
    0 0 0
    

    Sample Output

    9
    No Solution
    

    Source

    【分析】
    时间卡得真紧TAT,被T出翔。
    后面用HASH + 链表才过...
      1 /*
      2 五代李煜
      3 《浪淘沙令·帘外雨潺潺》
      4 帘外雨潺潺,春意阑珊。罗衾不耐五更寒。梦里不知身是客,一晌贪欢。
      5 独自莫凭栏,无限江山,别时容易见时难。流水落花春去也,天上人间。
      6 */ 
      7 #include <iostream>
      8 #include <cstdio>
      9 #include <ctime>
     10 #include <cmath>
     11 #include <algorithm>
     12 #include <cstring>
     13 #include <string>
     14 #include <map>
     15 #include <set>
     16 #include <vector> 
     17 #define LOCAL
     18 const int MAXN = 1000 + 10;
     19 const int maxn = 65535;//用来HASH 
     20 const int INF = 0x7fffffff;
     21 using namespace std;
     22 typedef long long ll;
     23 struct Hash{
     24        ll a,b,next;
     25 }Hash[maxn << 1];
     26 ll flg[maxn + 66];
     27 ll top,idx;
     28 void ins(ll a,ll b){
     29      ll k = b & maxn;
     30      if (flg[k] != idx){
     31         flg[k] = idx;
     32         Hash[k].next = -1;
     33         Hash[k].a = a;
     34         Hash[k].b = b;
     35         return ;
     36      }
     37      while (Hash[k].next != -1){
     38            if(Hash[k].b == b) return ;
     39            k = Hash[k].next;
     40      }
     41      Hash[k].next = ++ top;
     42      Hash[top].next = -1;
     43      Hash[top].a = a;
     44      Hash[top].b = b;
     45 }
     46 ll find(ll b){
     47     ll k = b & maxn;
     48     if (flg[k] != idx) return -1;
     49     while (k != -1){
     50           if(Hash[k].b == b) return Hash[k].a;
     51           k = Hash[k].next;
     52     }
     53     return -1;
     54 }
     55 ll gcd(ll a,ll b) {return b == 0? a: gcd(b, a % b);}
     56 ll exgcd(ll a, ll b, ll &x, ll &y){
     57     if (b == 0){x = 1; y = 0; return a;}
     58     ll tmp = exgcd(b, a % b, y, x);
     59     y -= x * (a / b);
     60     return tmp;
     61 }
     62 //求解线性同余方程 形如Ax = B(mod C) 
     63 ll solve(ll a, ll b, ll c){
     64     ll x, y, Ans; 
     65     ll tmp = exgcd(a, c, x, y);
     66     Ans = (ll)(x * b) % c;
     67     return Ans >= 0 ? Ans : Ans + c; 
     68 }
     69 ll pow(ll a, ll b, ll c){
     70     if (b == 1) return a % c;
     71     ll tmp = pow(a, b / 2, c);
     72     if (b % 2 == 0) return (tmp * tmp) % c;
     73     else return (((tmp * tmp) % c) * a) % c;
     74 }
     75 ll BSGS(ll A, ll B, ll C){
     76     top = maxn; 
     77     ++idx; 
     78     ll buf = 1 % C, D = buf, K, tmp;
     79     for (ll i = 0; i <= 100; i++){
     80         if (buf == B) return i;
     81         buf = (buf * A) % C;
     82     }
     83     ll d = 0;
     84     while ((tmp = gcd(A, C)) != 1){
     85           if (B % tmp != 0) return -1;
     86           d++;
     87           B /= tmp;
     88           C /= tmp;
     89           D = D * A / tmp % C;
     90     }
     91     //hash表记录1-sqrt(c)的值
     92     ll M = (ll)ceil(sqrt(C * 1.0)); 
     93     buf = 1 % C;
     94     for (ll i = 0; i <= M; i++){
     95         ins(i, buf);
     96         buf = (buf * A) % C;
     97     }
     98     K = pow(A, M, C);
     99     for (ll i = 0; i <= M; i++){
    100         tmp = solve(D, B, C);
    101         ll w;
    102         if (tmp >= 0 && (w = find(tmp)) != -1) return i * M + w + d;
    103         D = (D * K) % C;
    104     }
    105     return -1;
    106 }
    107 
    108 int main(){
    109     
    110     ll A, B, C;
    111     while (scanf("%lld%lld%lld", &A, &C, &B) != EOF){
    112           if (A == 0 && C == 0 && B == 0) break;
    113           B %= C;
    114           ll tmp = BSGS(A, B, C);
    115           if (tmp >= 0) printf("%lld
    ", tmp);
    116           else printf("No Solution
    ");
    117     }
    118     return 0;
    119 }
    View Code
  • 相关阅读:
    oracle 用户 权限
    oracle move 释放 表空间
    oracle 视图 参数
    js 、c# 编码解码
    Oracle实体化视图
    简单工厂VS工厂方法
    面向对象——(9)封装和接口
    写给明天的软件工程师——(转)
    设计模式简介
    设计模式的六大原则
  • 原文地址:https://www.cnblogs.com/hoskey/p/4352934.html
Copyright © 2011-2022 走看看