首先无视掉这题题面,您就全当机房的神犇在D蒟蒻我好了。
进入正题,首先这题的弱化版还是蛮好想的。设:
#include
#include
#include
#include
#include
#include
#include
#define s 20
using namespace std;
long long n,x,y;
long long prime[51],tot,b[51],ret[51];
long long ansi[320001],totans;
long long mult(long long a,long long b,long long p)
{
long long t;
if (b==0) return 0;
if (b==1) return a;
t=mult(a,b/2,p);
if (b%2==0) return (t+t)%p;
else return ((t+t)%p+a)%p;
}
long long power(long long a,long long b,long long p)
{
long long temp;
if (b==0) return 1;
if (b==1) return a;
temp=power(a,b/2,p);
if (b%2==0) return mult(temp,temp,p);
else return mult(a,mult(temp,temp,p),p);
}
bool check(long long a,long long n,long long x,long long t)
{
long long i,ret=power(a,x,n);
long long last=ret;
for (i=1;i<=t;++i)
{
ret=mult(ret,ret,n);
if (ret==1&&last!=1&&last!=n-1) return false;
last=ret;
}
if (ret!=1) return false;
else return true;
}
bool is_prime(long long n)
{
long long a,i,x,t=0;
if (n<2) return false;
if (n==2) return true;
if (!(n&1)) return false;
x=n-1;
if (!(x&1)) {x>>=1; t++;}
for (i=1;i<=s;++i)
{
a=rand()%(n-2)+2;
if (!check(a,n,x,t)) return false;
}
return true;
}
long long _abs(long long x)
{
if (x>0) return x;
else return -x;
}
long long gcd(long long a,long long b)
{
if (a%b==0) return b;
else return gcd(b,a%b);
}
long long pollard_rho(long long p)
{
long long y,d,k,i,x,x0,c;
c=(long long)(long long)(rand()*(long long)rand())%p;
y=x=(long long)((long long)rand()*(long long)rand())%p;
k=2; i=1;
while (true)
{
i++;
x=(mult(x,x,p)+c)%p;
d=gcd(_abs(y-x),p);
if (d!=1) return d;
if (i==k)
{y=x; k<<=1;}
}
}
void make_list(long long n)
{
long long i;
long long x,minn;
bool f,d;
f=is_prime(n);
if (f)
{
d=false;
for (i=1;i<=tot;++i)
if (prime[i]%n==0)
{prime[i]*=n; d=true;}
if (!d) prime[++tot]=n;
}
else
{
minn=pollard_rho(n);
while (minn==n) minn=pollard_rho(n);
make_list(minn);
make_list(n/minn);
}
}
void exgcd(long long a,long long b,long long p)
{
long long t;
if (a%b==0)
{
x=0;
y=1;
}
else
{
exgcd(b,a%b,p);
t=x%p;
x=y%p;
y=(t-mult((a/b),y,p)+p)%p;
}
}
void make_ret()
{
long long i,now,t;
for (i=1;i<=tot;++i)
{
now=n/prime[i];
now=now%prime[i];
exgcd(now,prime[i],prime[i]);
x=(x%prime[i]+prime[i])%prime[i];
t=n/prime[i];
ret[i]=mult(x,t,n);
}
}
void solve()
{
long long i,now,ans=0,t;
for (i=1;i<=tot;++i)
{
x=mult(ret[i],b[i],n);
ans=(ans+x)%n;
}
ansi[++totans]=ans;
}
void work(long long i)
{
if (i==tot+1)
{
solve();
return;
}
if (prime[i]==2)
{b[i]=1; work(i+1);}
else
{
b[i]=prime[i]-1; work(i+1);
b[i]=1; work(i+1);
if (prime[i]%2==0&&prime[i]>4)
{
b[i]=prime[i]/2+1;
work(i+1);
b[i]=prime[i]/2-1;
work(i+1);
}
}
}
int main()
{
long long i,size;
scanf("%lld",&n);
if (n==1) printf("None\n");
else
{
make_list(n);
make_ret();
work(1);
sort(ansi+1,ansi+totans+1);
size=unique(ansi+1,ansi+totans+1)-ansi-1;
for (i=1;i<=size-1;++i)
printf("%lld ",ansi[i]);
printf("%lld\n",ansi[size]);
}
}