1 条题解
-
1
#include<stdio.h> #include<vector> #include<ext/pb_ds/assoc_container.hpp> typedef long long ll; bool f; int lp,le,e[2000001]; ll n,m,k,p[21],pw[21],c[21]; std::vector<ll>r[21]; __gnu_pbds::gp_hash_table<ll,ll>h; ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} ll Pow(ll a,ll b,ll m) { ll s=1; for(a%=m;b;a=a*a%m,b>>=1) if(b&1) s=s*a%m; return s; } ll BSGS(ll a,ll b,ll m) { a%=m,b%=m,h.clear(); if(b==1) return 0; if(!a&&b) return -1; ll s=sqrt(m)+1,aa=1; for(ll i=0;i<s;i++) h[b*aa%m]=i,aa=aa*a%m; for(ll i=1,j=aa;i<=s;i++,j=j*aa%m) { int x=h[j]; if(x||j==b) return i*s-x; } return -1; } ll exgcd(ll a,ll b,ll&x,ll&y) { if(!b) return x=1,y=0,a; int g=exgcd(b,a%b,y,x); return y-=a/b*x,g; } bool DiscreteRoots(ll z) { if(k%pw[z]) { ll kp=k%pw[z],pk=1,mk=0; while(kp%p[z]==0) kp/=p[z],pk*=p[z],mk++; if(mk%n) return 1; ll pwk=pw[z]/pk,h=pwk/p[z]*(p[z]-1),g,le=0,e[21]; if(Pow(kp,h/gcd(n,h),pwk)!=1) return 1; for(ll i=2;i*i<=h;i++) if(h%i==0) { while(h%i==0) h/=i; e[le++]=i; } if(h>1) e[le++]=h; for(g=1;;g++) { bool f=1; for(int i=0;i<le&&f;i++) if(Pow(g,pwk/p[z]*(p[z]-1)/e[i],pwk)==1) f=0; if(f) break; } ll x=BSGS(g,kp,pwk),ka,kb,y=exgcd(n,pwk/p[z]*(p[z]-1),ka,kb); if(x%y) return 1; h=pwk/p[z]*(p[z]-1)/y,kb=Pow(p[z],mk/n,pw[z]),r[z].resize(y*(pk/kb)),r[z][0]=Pow(g,(ka*(x/y)%h+h)%h,pwk),ka=kb,kb=Pow(g,h,pwk); for(ll i=1;i<y;i++) r[z][i]=r[z][i-1]*kb%pwk; for(ll i=y;i<y*(pk/ka);i++) r[z][i]=(r[z][i-y]+pwk)%(pw[z]/ka); for(ll i=0;i<y*(pk/ka);i++) r[z][i]=r[z][i]*ka; } else { ll x=0,y=1,o=Pow(p[z],n,pw[z]); while(y) x++,y=y*o%pw[z]; r[z].resize(o=pw[z]/(y=Pow(p[z],x,pw[z]+1))); for(ll i=0;i<o;i++) r[z][i]=i*y; } return 0; } void dfs(ll st,ll x) { if(st==lp) { e[le++]=x; return; } for(ll i:r[st]) dfs(st+1,(x+i*c[st])%m); return; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%lld%lld%lld",&n,&m,&k),f=1,lp=le=0; if(n==1) { printf("1\n%lld\n",k); continue; } if(!(m&7)) { ll mp=3; p[0]=2,pw[0]=8,m>>=3; while(!(m&1)) m>>=1,pw[0]<<=1,mp++; if(k&pw[0]-1) { ll k2=k&pw[0]-1,r2=0; while(!(k2&1)) k2>>=1,r2++; if(r2%n) { puts("0"); continue; } if(pw[0]>>r2>4) { ll w_1=0,w5=BSGS(5,k2,pw[0]>>r2); if(!~w5) w_1=1,w5=BSGS(5,(pw[0]>>r2)-k2,pw[0]>>r2); if(n&1) { ll x,y,g=exgcd(n,pw[0]>>r2+2,x,y); if(w5%g) { puts("0"); continue; } w5/=g,x=x*w5&(pw[0]>>r2+2)/g-1,y=Pow(5,(pw[0]>>r2+2)/g,pw[0]>>r2),r[0].resize(g),r[0][0]=w_1?(pw[0]>>r2)-Pow(5,x,pw[0]>>r2):Pow(5,x,pw[0]>>r2); for(ll i=1;i<g;i++) r[0][i]=r[0][i-1]*y&(pw[0]>>r2)-1; } else if(w_1) { puts("0"); continue; } else { ll x,y,g=exgcd(n,pw[0]>>r2+2,x,y); if(w5%g) { puts("0"); continue; } w5/=g,x=x*w5&(pw[0]>>r2+2)/g-1,y=Pow(5,(pw[0]>>r2+2)/g,pw[0]>>r2),r[0].resize(g<<1),r[0][g]=(pw[0]>>r2)-(r[0][0]=Pow(5,x,pw[0]>>r2)); for(ll i=1;i<g;i++) r[0][i]=r[0][i-1]*y&(pw[0]>>r2)-1,r[0][i+g]=r[0][i+g-1]*y&(pw[0]>>r2)-1; } } else for(ll i=0;i<pw[0]>>r2;i++) if(Pow(i,n,pw[0]>>r2)==k&(pw[0]>>r2)-1) r[0].emplace_back(i); ll s=r[0].size(); r[0].resize(s<<r2-r2/n); for(ll i=s;i<s<<r2-r2/n;i++) r[0][i]=r[0][i-s]+(pw[0]>>r2)&(pw[0]>>r2/n)-1; for(ll i=0;i<s<<r2-r2/n;i++) r[0][i]=r[0][i]<<r2/n; } else { ll l=1ll<<mp-(mp-1)/n-1; r[0].resize(l); for(ll i=0;i<l;i++) r[0][i]=i<<(mp-1)/n+1; } lp++; } else if(!(m&3)) { p[0]=2,pw[0]=4,m>>=2; for(ll i=0;i<4;i++) if(Pow(i,n,4)==(k&3)) r[0].emplace_back(i); if(r[0].empty()) { puts("0"); continue; } lp++; } else if(!(m&1)) p[0]=2,pw[0]=2,m>>=1,r[0].emplace_back(k&1),lp++; for(ll i=3;i*i<=m;i+=2) if(m%i==0) { p[lp]=i,pw[lp]=1; while(m%i==0) m/=i,pw[lp]*=i; if(DiscreteRoots(lp)) { f=0; break; } lp++; } if(!f) { puts("0"); while(lp--) r[lp].clear(); continue; } if(m>1) { p[lp]=pw[lp]=m,m=1; if(DiscreteRoots(lp)) { puts("0"); while(lp--) r[lp].clear(); continue; } lp++; } for(ll i=0;i<lp;i++) m*=pw[i]; for(ll i=0;i<lp;i++) c[i]=m/pw[i]*Pow(m/pw[i],pw[i]/p[i]*(p[i]-1)-1,pw[i])%m; dfs(0,0),std::sort(e,e+le),printf("%lld\n",le); for(ll i=0;i<le;++i,i<le?putchar(' '):putchar('\n')) printf("%lld",e[i]); while(lp--) r[lp].clear(); } return 0; }
- 1
信息
- ID
- 9719
- 时间
- 2000ms
- 内存
- 128MiB
- 难度
- 9
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者