BZOJ 1420&&BZOJ 1319 Discrete Roots 数论

来源:互联网 发布:姚明各个赛季的数据 编辑:程序博客网 时间:2024/05/29 10:57

题目大意:求方程xka(mod p)[0,p)区间内的全部解
p的一个原根g,两侧取指标得到:
kindgxindga(mod p1)
上EXGCD即可
注意a=0要特判
(EXGCD已死系列……

#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define INF 0x3f3f3f3f3f3f3f3fllusing 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;}
0 0
原创粉丝点击