1 条题解

  • 1
    @ 2026-8-6 10:24:14
    
    #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
    上传者