IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 【Gym103261D】FFT Algorithm (Carmichael function + Pollard Rho) -> 正文阅读

[游戏开发]【Gym103261D】FFT Algorithm (Carmichael function + Pollard Rho)

题目链接

题目大意

给定 m , k ( m ≤ 1 0 18 , 15 ≤ k ≤ 23 ) m, k (m\le 10^{18}, 15\le k\le 23) m,k(m1018,15k23) ,求一个数 w w w 满足:

  • w 2 k ≡ 1 ( m o d m ) w^{2^k}\equiv 1\pmod m w2k1(modm)
  • w 2 k ? 1 ≡? 1 ( m o d m ) w^{2^{k-1}}\not\equiv 1\pmod m w2k?1?1(modm)

思路

Carmical 函数 λ ( n ) = max ? { o ( a ) ∣ a ⊥ n } \lambda(n)=\max\{o(a)\mid a\perp n\} λ(n)=max{o(a)an}
答案存在当且仅当 2 k ∣ λ ( m ) 2^k|\lambda(m) 2kλ(m)
其中

  • λ ( 2 ) = 1 \lambda(2)=1 λ(2)=1
  • λ ( 4 ) = 2 \lambda(4)=2 λ(4)=2
  • λ ( 2 k ) = 2 k ? 2 ( k ≥ 3 ) \lambda(2^k)=2^{k-2}(k\ge 3) λ(2k)=2k?2(k3)
  • λ ( p k ) = p k ? 1 ( p ? 1 ) ( p ≥ 3 ) \lambda(p^k)=p^{k-1}(p-1)(p\ge 3) λ(pk)=pk?1(p?1)(p3)
  • λ ( u v ) = lcm ( λ ( u ) , λ ( v ) ) ( u ⊥ v ) \lambda(uv)=\text{lcm} (\lambda(u), \lambda(v))(u\perp v) λ(uv)=lcm(λ(u),λ(v))(uv)

原根存在的充要条件是 λ ( n ) = φ ( n ) \lambda(n)=\varphi(n) λ(n)=φ(n) ,即 n = 1 , 2 , 4 , p k , 2 p k ( p ≥ 3 ) n=1,2,4,p^k, 2p^k(p\ge 3) n=1,2,4,pk,2pk(p3)

为了求 λ ( m ) \lambda(m) λ(m) ,需要对 m m m 进行质因数分解。可以采用 Pollard Rho 算法:

  1. 利用 Miller-Rabin 判断本身是否是质数
  2. 如果不是质数,随机一个序列 x , f ( x ) , f ( f ( x ) ) , . . . x,f(x),f(f(x)),... x,f(x),f(f(x)),... ,其中 f ( x ) = x 2 + c f(x)=x^2+c f(x)=x2+c (这样可以保证 x 1 ? x 2 ∣ f ( x 1 ) ? f ( x 2 ) x_1-x_2|f(x_1)-f(x_2) x1??x2?f(x1?)?f(x2?)),序列最后会形成一个 ρ \rho ρ 形。我们可以搞两个变量 x 1 , x 2 x_1,x_2 x1?,x2? ,初始都设成 x x x ,然后每次迭代时令 x 1 = f ( x 1 ) , x 2 = f ( f ( x 2 ) ) x_1=f(x_1), x_2=f(f(x_2)) x1?=f(x1?),x2?=f(f(x2?)) ,依次检验即可。如果遇到套圈的情况,就换个种子重新生成。(实际操作时,一般让 x = 2 , c = 1 x=2,c=1 x=2,c=1 ,127步为一组判断。如果套圈就令 c + + c++ c++ )期望复杂度 O ( n 1 4 ) O(n^{\frac{1}{4}}) O(n41?)

求出来后,随机一些 x x x ,令 w = x λ ( m ) 2 k w=x^\frac{\lambda(m)}{2^k} w=x2kλ(m)? ,多试一些就能出答案。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll prime[12] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
ll mul(ll x, ll y, ll mod) {  // can also use __int128 on Linux
    ll ret = 0;
    while (y) {
        if (y & 1) ret = (ret + x) % mod;
        x = x * 2 % mod;
        y >>= 1;
    }
    return ret;
}
ll pw(ll x, ll y, ll mod) {
    ll ret = 1;
    while (y) {
        if (y & 1) ret = mul(ret, x, mod);
        x = mul(x, x, mod);
        y >>= 1;
    }
    return ret;
}
bool isprime(ll x) {
    if (x == 1) return false;
    for (int i = 0; i < 12; ++i) {
        if (x == prime[i]) return true;  // special(itself)
        ll t = x - 1;
        if (pw(prime[i], t, x) != 1) return false;  // failure
        while (t % 2 == 0) {
            t >>= 1;
            ll now = pw(prime[i], t, x);
            if (now == x - 1) break;
            if (now != 1) return false;  // failure
        }
    }
    return true;
}
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
ll lcm(ll x, ll y) { return x / gcd(x, y) * y; }
ll pollard_rho(ll x) {
    if (x % 2 == 0) return 2;  // special(unable to generate 2)
    ll x1 = 2, x2 = 2, c = 1;
    while (1) {
        ll y1 = x1, y2 = x2, y = 1;
        for (int i = 1; i <= 127; ++i) {
            y1 = (mul(y1, y1, x) + c) % x;
            y2 = (mul(y2, y2, x) + c) % x;
            y2 = (mul(y2, y2, x) + c) % x;
            y = mul(y, y2 - y1 + x,
                    x);  // to generate possible (times of factors)
        }
        y = gcd(y, x);
        if (y == x) {  // rejudge one by one
            for (int i = 1; i <= 127; ++i) {
                x1 = (mul(x1, x1, x) + c) % x;
                x2 = (mul(x2, x2, x) + c) % x;
                x2 = (mul(x2, x2, x) + c) % x;
                y = gcd(x2 - x1 + x, x);
                if (y == x)
                    ++c;
                else if (y > 1)
                    return y;
            }
        } else if (y > 1)
            return y;
        x1 = y1;
        x2 = y2;
    }
}
ll sta[1005], top = 0;
void decompose(ll x) {
    if (x == 1) return;
    if (isprime(x)) {
        sta[++top] = x;
        return;
    }
    ll t = pollard_rho(x);
    decompose(t);
    decompose(x / t);
}
ll m;
int k;
ll solve() {
    int cnt = 0;
    ll x = m;
    while (x % 2 == 0) {
        x >>= 1;
        ++cnt;
    }
    ll lambda;
    if (cnt <= 1)
        lambda = 1;
    else if (cnt == 2)
        lambda = 2;
    else
        lambda = (1ll << cnt - 2);
    top = 0;
    decompose(x);
    sort(sta + 1, sta + top + 1);
    for (int i = 1, last; i <= top; i = last + 1) {
        ll tmp = sta[i] - 1;
        last = i;
        while (last < top && sta[last + 1] == sta[i]) {
            ++last;
            tmp *= sta[i];
        }
        lambda = lcm(lambda, tmp);
    }
    // printf("%lld\n", lambda);
    if (lambda & ((1ll << k) - 1))
        return -1;
    else {
        for (ll x = 1; x < m; x++) {
            if (gcd(x, m) > 1) continue;
            ll w = pw(x, lambda >> k, m);
            if (pw(w, 1ll << k - 1, m) != 1) return w;
        }
    }
    return -2;
}
int main() {
    scanf("%lld%d", &m, &k);
    printf("%lld", solve());

    return 0;
}
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-10-16 19:56:59  更:2021-10-16 19:59:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 0:44:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码