bzoj1420/1319 Discrete Root

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1420

http://www.lydsy.com/JudgeOnline/problem.php?id=1319

【题解】

求x^A=B(mod P),其中P是质数。

考虑对两边取log,设g为P的原根。

Alog(x) = log(B) (mod P-1)

log(x)表示以g为底的log

那么log(B) = y,其中g^y = B (mod P),用BSGS求出即可。

我们要求的是x,不妨先求log(x),设ans=log(x)

那么A*ans + (P-1)*k = y。这是一个exgcd的形式,所以我们可以求出ans的所有解(由于相当于指数,所以必须小于P-1)

然后快速幂即可。

# include <map>
# include <math.h>
# include <stdio.h>
# include <assert.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

ll A, B, P, B0;
ll g, ans[M]; int ansn=0;

inline ll pwr(ll a, ll b, ll P) {
    ll ret = 1; a %= P;
    while(b) {
        if(b&1) ret = ret * a % P;
        a = a * a % P;
        b >>= 1;
    }
    return ret;
}

ll y[M];
inline ll G(ll x) {
    ll t = x; int nn = 0;
    for (int i=2; i*i<=x; ++i) {
        if(x%i) continue;
        y[++nn] = i;
        while(x%i == 0) x/=i;
    }
    if(x != 1) y[++nn] = x;
    for (ll g=2; ; ++g) {
        bool flag = 1;
        for (int i=1; i<=nn; ++i)
            if(pwr(g, t/y[i], P) == 1) {
                flag = 0;
                break;
            }
        if(flag) return g;
    }
}

map<ll, int> mp;
inline ll BSGS(ll A, ll B, ll P) {
    mp.clear();
    int m = ceil(sqrt(1.0 * P));
    ll t = B, g;
    for (int i=0; i<m; ++i) {
        if(!mp[t]) mp[t] = i;
        t = t * A % P;
    }
    g = pwr(A, m, P); t = g;
    for (int i=1, ps; i<=m+1; ++i) {
        if(mp.count(t)) return (ll)i*m - mp[t];
        t = t * g % P;
    }
    return -1;
}

ll exgcd(ll a, ll b, ll &x, ll &y) {
    if(b == 0) {
        x = 1, y = 0;
        return a;
    }
    ll ret = exgcd(b, a%b, x, y), t;
    t = x;
    x = y;
    y = t - (a/b) * y;
    return ret;
}

int main() {
    cin >> P >> A >> B;
    g = G(P-1);
//    cout << g << endl;
    // x^A = B (mod P)
    // A log_g(x) = log_g(B) (mod P-1)
    B0 = BSGS(g, B, P);
    assert(B0 != -1);
//    cout << B0 << endl;
    ll tx, ty, GCD;
    GCD = exgcd(A, P-1, tx, ty);
    if(B0 % GCD) {
        puts("0");
        return 0;
    }

    ty = (P-1)/GCD;
    tx = (tx % ty + ty) % ty;
    tx = (tx * B0/GCD) % ty;
    while(tx < P-1) {
        ans[++ansn] = pwr(g, tx, P);
        tx += ty;
    }
    sort(ans+1, ans+ansn+1);

    cout << ansn << endl;
    for (int i=1; i<=ansn; ++i)
        printf("%lld\n", ans[i]);
    return 0;
}

时间: 2024-10-12 17:00:43

bzoj1420/1319 Discrete Root的相关文章

BZOJ 2701&amp;&amp;BZOJ 1319 Discrete Roots 数论

题目大意:求方程xk≡a(mod p)在[0,p)区间内的全部解 取p的一个原根g,两侧取指标得到: k?indgx≡indga(mod p?1) 上EXGCD即可 注意a=0要特判 (EXGCD已死系列-- #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define INF 0x3f3f3f3f3f3

UVA - 1426 Discrete Square Roots (模方程)

Description A square root of a number x is a number r such that r2 = x. A discrete square root of a non-negative integer x is a non-negative integer r such that r2 x mod N , 0r < N , where N is a specific positive integer and mod is the modulo operat

PP: Deep r -th Root of Rank Supervised Joint Binary Embedding for Multivariate Time Series Retrieval

from: Dacheng Tao 悉尼大学 PROBLEM: time series retrieval: given the current multivariate time series segment, how to obtain its relevant time series segments in the historical data. Two challenging: 1. it requires a compact representation of the raw tim

LeetCode OJ - Sum Root to Leaf Numbers

这道题也很简单,只要把二叉树按照宽度优先的策略遍历一遍,就可以解决问题,采用递归方法越是简单. 下面是AC代码: 1 /** 2 * Sum Root to Leaf Numbers 3 * 采用递归的方法,宽度遍历 4 */ 5 int result=0; 6 public int sumNumbers(TreeNode root){ 7 8 bFSearch(root,0); 9 return result; 10 } 11 private void bFSearch(TreeNode ro

《linux破解root密码》

以下实验操作基于RHEL7.0下进行 步骤如下: 1. 重启系统 2. 按任意键,以中断启动加载器的倒计时. 3. 把光标移动到需要启动的条目. 4. 按e键,编辑该条目 把光标移动到linux16开头的行. 删除 console=ttys0,115200n8 在该行末尾,输入一个空格,然后添加  rd.break 注:rd.break表示控制权从initramfs转移到实际系统之前,进行中断. 5.  ctrl+x使用该改动并启动 启动好后,实际的根文件系统,以只读方式挂载到 /sysroot

MySQL更改默认的root账户密码

编辑mysql的配置文件:my.ini(在MySql安装目录下). 打开配置文件,在文件最后一行添加:skip-grant-tables,然后保存退出 意思为就是在启mysql时不启动grant-tables 重启MySql服务:(在命令行窗口中,需要事先把MySQL的bin路径添加到环境变量当中,或者通过在服务中重新启动) net stop mysql net start mysql 设置新的root密码 mysql -u root -p 直接回车,无需输入密码就可以进入数据库了.(或者直接敲

129. Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. For example, 1 / 2 3 T

linux下添加用户并赋予root权限

1.添加用户,首先用adduser命令添加一个普通/系统用户,命令如下:# adduser [-r] –d /tommy tommy//添加一个名为tommy的用户 # passwd tommy   //修改密码Changing password for user tommy.New UNIX password:     //在这里输入新密码Retype new UNIX password:  //再次输入新密码passwd: all authentication tokens updated

Nignx入门location、root配置

nginx的配置.首当其冲的就是location配置了,下面是笔记参考的博文链接点这里 location匹配的是nginx的哪个变量? $request_uri (这个不懂怎么用) location的匹配种类有哪些? 格式 location [ 空格 | = | ~ | ~* | !~ | !~* ] /uri/ {} # 精确匹配: 相等(=) # 字符串匹配: 字符串匹配(空格) 匹配开头(^~) # 正则匹配: 区分大小写匹配(~) 不区分大小写匹配(~*) 区分大小写不匹配(!~) 不区