#include #include #include #define ll long long #define ull unsigned long long ll mulmod(ll a,ll n,ll m){ ull x=0; a%=m,n%=m; while(n){ if(n%2)x=(x+a)%m; a=(a+a)%m; n/=2; } return (ll)x; } ll powmod(ll a,ll n,ll m){ ll x=1; a%=m; while(n){ if(n%2)x=mulmod(x,a,m); a=mulmod(a,a,m); n/=2; } return x; } ll gcd(ll x,ll y){ while(y){ ll t=x%y; x=y; y=t; } return x; } ll inv(ll a,ll p){ ll b=p,tx,ty,t,x=1,y=0,x2=0,y2=1; while(b){ tx=x-a/b*x2;x=x2;x2=tx; ty=y-a/b*y2;y=y2;y2=ty; t=a%b;a=b;b=t; } if(a!=1)return-1; return x>0?x:x+p; } ll intsqrt(ll n){ ll x=sqrt(n); while((x+1)*(x+1)<=n)x++; return x; } ll intcbrt(ll n){ ll x=cbrt(n); while((x+1)*(x+1)*(x+1)<=n)x++; return x; } typedef struct pair{ll a;int n;}P; int Pcmp(const void*p,const void*q){ if((*(P*)p).a<(*(P*)q).a)return -1; return 1; } P memo[100000]; int memosize; void subsubpre(ll g,ll p,ll mod){ //(Z/modZ)^*における位数pの元gに対し //g^-nを0<=n<=sqrt(p)くらいの範囲でメモ g=inv(g,mod); memosize=sqrt(p)+10; ll x=1; for(int i=0;i1){ int m=(l+r)/2; if(memo[m].a<=x)l=m; else r=m; } if(memo[l].a==x)return i*memosize+memo[l].n; x=mulmod(x,gM,mod); } } ll modrootsub(ll a,ll p,ll e,ll mod){ // 0 < e < ord_p(mod-1) ll q=mod-1; int s=0; while(q%p==0)q/=p,s++; // Z/(p^s)Z * Z/qZ ll pe=1; for(int i=0;i=2なので //そのようなqであってp^(1/4)より大きなものは高々1つ for(ll i=2;i*i*i*i<=p-1;i++)if(d2%i==0){ d2/=i; int e=1; while(d2%i==0)d2/=i,e++; a=modrootsub(a,i,e,p); } if(d2!=1){ //d2はp^(1/4)より大きな素数qか、その平方 //(ord_q(d2)