BZOJ 2701&&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 0x3f3f3f3f3f3f3f3fll
using namespace std;
typedef pair<long long,long long> abcd;
long long p,k,a;
long long Quick_Power(long long x,long long y)
{
    long long re=1;
    while(y)
    {
        if(y&1) (re*=x)%=p;
        (x*=x)%=p; y>>=1;
    }
    return re;
}
long long Get_Primitive_Root(long long p)
{
    static long long stack[100],top;
    long long i,j,temp=p-1;
    for(i=2;i*i<=temp;i++)
        if(temp%i==0)
        {
            stack[++top]=i;
            while(temp%i==0)
                temp/=i;
        }
    if(i!=1) stack[++top]=i;
    for(i=1;i<p;i++)
    {
        for(j=1;j<=top;j++)
            if(Quick_Power(i,(p-1)/stack[j])==1)
                break;
        if(j==top+1)
            return i;
    }
    while(1) puts("");
}
namespace Hash_Set{
    struct List{
        long long hash,val;
        List *next;
        List(long long _,List *__):
            hash(_),val(INF),next(__) {}
    }*head[10001];
    long long& Hash(long long x)
    {
        int pos=x%10001;
        List *temp=head[pos];
        for(temp=head[pos];temp;temp=temp->next)
            if(temp->hash==x)
                return temp->val;
        return (head[pos]=new List(x,head[pos]))->val;
    }
}
abcd EXGCD(long long x,long long y)
{
    if(!y) return abcd(1,0);
    abcd temp=EXGCD(y,x%y);
    return abcd(temp.second,temp.first-x/y*temp.second);
}
long long Baby_Step_Giant_Step(long long A,long long B)
{
    long long i,m=ceil(sqrt(p)),temp=1,D=1;
    for(i=0;i<=m;i++,(temp*=A)%=p)
    {
        long long &val=Hash_Set::Hash(temp);
        val=min(val,i);
        D=temp;
    }
    for(temp=1,i=0;i<=m;i++,(temp*=D)%=p)
    {
        long long x=(EXGCD(temp,p).first%p+p)%p;
        long long &val=Hash_Set::Hash(x*B%p);
        if(val!=INF) return i*m+val;
    }
    while(1) puts("");
}
int main()
{
    long long i;
    cin>>p>>k>>a;
    if(a==0)
    {
        printf("1\n0\n");
        return 0;
    }
    long long g=Get_Primitive_Root(p);
    a=Baby_Step_Giant_Step(g,a);
    long long gcd=__gcd(k,p-1);
    if(a%gcd)
    {
        printf("0\n");
        return 0;
    }
    static long long stack[100100],top;
    long long temp=(p-1)/gcd;
    long long origin=(EXGCD(k,p-1).first%temp+temp)%temp;
    (origin*=a/gcd)%=temp;
    for(i=origin;i<p-1;i+=temp)
        stack[++top]=Quick_Power(g,i);
    sort(stack+1,stack+top+1);
    cout<<top<<endl;
    for(i=1;i<=top;i++)
        printf("%lld\n",stack[i]);
    return 0;
}
时间: 2024-08-22 18:44:24

BZOJ 2701&&BZOJ 1319 Discrete Roots 数论的相关文章

UVA 1426 - Discrete Square Roots(数论)

UVA 1426 - Discrete Square Roots 题目链接 题意:给定X, N, R,要求r2≡x (mod n) (1 <= r < n)的所有解,R为一个已知解 思路: r2≡x (mod n)=>r2+k1n=x 已知一个r!,带入两式相减得 r2?r12=kn => (r+r1)(r?r1)=kn 枚举A,B,使得 A * B = n (r + r1)为A倍数 (r - r1)为B倍数 这样就可以推出 Aka?r1=Bkb+r1=r => Aka=Bk

261. Discrete Roots

给定\(p, k, A\),满足\(k, p\)是质数,求 \[x^k \equiv A \mod p\] 不会... 1 #include <iostream> 2 #include <map> 3 #include <cstdio> 4 #include <algorithm> 5 #include <cstring> 6 #include <vector> 7 #include <cmath> 8 using nam

SGU 261 Discrete Roots N次剩余

链接:vjudge 题意:给出两个素数P,K (2 <= P <= 10^9, 2 <= K <= 100000)和一个整数A (0 <= A < P) ,找出 x ^ K ≡ A mod P的解. 思路:N次剩余,模板题,复杂度O(sqrt(p)). 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include

点分治专题——bzoj 1468 &amp;bzoj 2152 题解

[前言]最近一直在忙着学算法,但是效果似乎不是很好.前段时间的树剖也快忘了= =.树套树没熟练,就开始写主席树了= =.更别说本身就不是很懂的莫比乌斯反演了.~~决定好好复习一下. [点分治的作用]套用SYC大神的话说是:用来解决树上路径点权统计问题. [大致流程] ①找出这颗树的重心. ②统计经过这个重心的答案 ③用重心把树割开 ④对每个"小树"做同样的事 [Q1--重心]其实找重心再进行计算只是为了不被卡链.什么是重心?就是当前树中的一个点K,使得MAX(SON[K])最小.SON

[poj 2417]Discrete Logging 数论 BSGS

Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3516   Accepted: 1651 Description Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarithm of N, base B, modulo P.

BZOJ 1257: [CQOI2007]余数之和sum( 数论 )

n >= k 部分对答案的贡献为 k * (n - k) n < k 部分贡献为 ∑ (k - ⌊k / i⌋ * i)  = ∑  , ⌊k / i⌋ 相等的数是连续的一段, 此时这段连续的数对答案的贡献成等差数列, 可以O(1)求出..然后就分⌊k / i⌋ 相等的一块一块来就行了. 分出来大概是sqrt(k)块.这个sqrt(k)我并不会证Orz...写了个程序验证了一下, 分出来的块数和2 * sqrt(k)非常接近. 所以时间复杂度为O(sqrt(k)) --------------

BZOJ 3992: [SDOI2015]序列统计 [快速数论变换 生成函数 离散对数]

3992: [SDOI2015]序列统计 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1017  Solved: 466[Submit][Status][Discuss] Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S. 小C用这个生成器生成了许多这样的数列.但是小C有一个问题需要你的帮助:给定整数x,求所有可以生成出的,且满足数列中

BZOJ 2705: [SDOI2012]Longge的问题( 数论 )

---恢复内容开始--- T了一版....是因为我找质因数的姿势不对... 考虑n的每个因数对答案的贡献. 答案就是 ∑ d * phi(n / d) (d | n) 直接枚举n的因数然后求phi就行了. 但是我们可以做的更好. 注意到h(n) = ∑ d * phi(n / d) (d | n) 是狄利克雷卷积的形式, 而且f(x) = x 和 f(x) = phi(x) 都是积性函数, 所以答案h(x) 也是积性函数. 所以h(x) = Π h(p^k) (p 是 x 的质因数) 由phi(

BZOJ 3992 Sdoi2015 序列统计 快速数论变换

题目大意:给定n(n<=10^9),质数m(3<=m<=8000),1<=x=m,以及一个[0,m-1]区间内的集合S,求有多少长度为n的数列满足每个元素都属于集合S且所有元素的乘积mod m后=x 求原根,对S集合内每个元素取指标,然后搞出生成函数f(x) 那么答案就是(f(x))^n (mod x^(m-1),mod 1004535809) 上NTT用多项式快速幂搞一搞就好了 #include <cstdio> #include <cstring> #i