您的位置:首页 > 其它

[原根 指标 模方程 BSGS] BZOJ 1420 Discrete Root & BZOJ 1319 Sgu261Discrete Roots

2016-07-28 08:28 337 查看
求个指标

解个方程就好了

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long ll;
typedef pair<ll,ll> abcd;

inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}

inline void read(ll &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

inline ll Pow(ll a,ll b,ll p)
{
ll ret=1;
for (;b;(a*=a)%=p,b>>=1)
if (b&1)
(ret*=a)%=p;
return ret;
}

ll f[1000005];

inline ll GetRoot(ll p,ll phi)
{
int c=0;
for (int i=2;i*i<=phi;i++) if (phi%i==0) f[++c]=i,f[++c]=phi/i;
for (ll g=2;g<p;g++){
int j;
for (j=1;j<=c;j++)
if (Pow(g,f[j],p)==1)
break;
if (j==c+1) return g;
}
return 0;
}

namespace Math{
inline abcd EXGCD(ll a,ll b){
if (a<b) { abcd ret=EXGCD(b,a); return abcd(ret.second,ret.first); }
if (!b) return abcd(1,0);
abcd ret=EXGCD(b,a%b);
return abcd(ret.second,ret.first-a/b*ret.second);
}
inline void Solve(ll A,ll B,ll N,vector<ll> &ans){
A%=N; B%=N;
if (!A && !B) { for (int i=0;i<N;i++) ans.push_back((ll)i); return; }
if (!A && B) return;
if (!B && A) { ans.push_back(0); return; }
abcd E=EXGCD(A,N);
ll D=A*E.first+N*E.second,X;
if (B%D==0)
{
X=E.first*(B/D)%N; X=(X%N+N)%N;
for (int i=0;i<D;i++)
{
ans.push_back(X);
(X+=(N/D))%=N;
}
}
}
}

namespace BSGS{
struct hashmap{
#define MOD 1000007
ll num;
ll key[1000005],value[1000005],next[1000005];
ll head[MOD];
inline void insert(ll k,ll v){
ll ad=k%MOD; key[++num]=k; value[num]=v; next[num]=head[ad]; head[ad]=num;
}
inline ll operator[](ll k){
ll ad=k%MOD;
for (int p=head[ad];p;p=next[p]) if (key[p]==k) return value[p];
return -1;
}
inline void clear(){
cl(head); num=0;
}
}M;
inline ll Solve(ll A,ll B,ll P,ll phi)
{
M.clear();
A%=P;
if (!A && !B) return 1;
if (!A) return -1;
ll m=sqrt((double)P)+1,tmp=1;
M.insert(1,0);
for (int i=1;i<m;i++){
(tmp*=A)%=P;
if (M[tmp]==-1) M.insert(tmp,i);
}
ll inv=1,T=Pow(A,phi-m,P);
for (int k=0;k<m;k++){
ll i=M[B*inv%P];
if (i!=-1) return k*m+i;
(inv*=T)%=P;
}
return -1;
}
}

ll P,K,A,G;
vector<ll> Ans;

int main()
{
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(P); read(K); read(A);
G=GetRoot(P,P-1);
A=BSGS::Solve(G,A,P,P-1);
Math::Solve(K,A,P-1,Ans);
for (int i=0;i<(signed)Ans.size();i++)
Ans[i]=Pow(G,Ans[i],P);
sort(Ans.begin(),Ans.end());
unique(Ans.begin(),Ans.end());
printf("%d\n",(signed)Ans.size());
for (int i=0;i<(signed)Ans.size();i++)
printf("%lld\n",Ans[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: