题解 循环
听说有个 \(O(b^2n)\) 的高端 DP?
反正放考场上也想不出来,直接说正解吧
将这个循环数写成无限循环小数的形式可以发现
\[\{1,2,\cdots,n\}=\{b^0,b^1,\cdots,b^{n-1}\}\pmod p
\]
可知 \(p>n\) 且可知 \(\exists{i},b^i=2\)
艹我不复读上面题解了
然后得出 \(\{1,2,\cdots,n\}\) 与 \(\{2,4,\cdots,2n\}\) 间关系
按 \(n=2m\) 和 \(n=2m+1\) 分类讨论得到 \(p=n+1\)
还可分析出 \(p\) 是质数且 \(b\) 是 \(p\) 的原根
所以从大到小判原根就好了
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 5000010
#define ll long long
#define ull unsigned long long
#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n, x;
#if 0
namespace table{
int a[N], c[N], cnt[N], rec[N];
void calc(int* a, int t, int b) {
for (int i=1; i<=n; ++i) c[i]+=a[i]*t;
for (int i=1; i<=n; ++i) c[i+1]+=c[i]/b, c[i]%=b;
}
bool dfs(int u, int b) {
if (u>n) {
for (int i=0; i<=b; ++i) rec[i]=0;
for (int i=1; i<=n; ++i) ++rec[a[i]];
//cout<<"a: "; for (int i=1; i<=n; ++i) cout<<a[i]<<' '; cout<<endl;
for (int i=1; i<=n; ++i) {
for (int j=1; j<=n+1; ++j) c[j]=0;
calc(a, i, b);
if (c[n+1]) return 0;
for (int j=0; j<=b; ++j) cnt[j]=0;
for (int j=1; j<=n; ++j) ++cnt[c[j]];
for (int j=0; j<=b; ++j) if (cnt[j]!=rec[j]) return 0;
cout<<"loop: "; for (int j=1; j<=n; ++j) cout<<a[j]<<' '; cout<<endl;
return 1;
}
}
for (int i=0; i<b; ++i) {
a[u]=i;
//if (dfs(u+1, b)) return 1;
dfs(u+1, b);
}
return 0;
}
void solve() {
for (int b=2; b<x; ++b) {
// if (dfs(1, b)) {cout<<b<<endl; return 0;}
cout<<"test: "<<b<<endl;
dfs(1, b);
}
}
}
namespace force{
const ull base=13131;
int a[N], c[N];
ull h[N], pw[N];
inline ull hashing(int l, int r) {return h[r]-h[l-1]*pw[r-l+1];}
void calc(int* a, int t, int b) {
for (int i=1; i<=n; ++i) c[i]+=a[i]*t;
for (int i=1; i<=n; ++i) c[i+1]+=c[i]/b, c[i]%=b;
}
bool dfs(int u, int b) {
if (u>n) {
//cout<<"a: "; for (int i=1; i<=n; ++i) cout<<a[i]<<' '; cout<<endl;
ull tem=0;
for (int i=1; i<=n; ++i) tem=tem*base+a[i];
if (!tem) return 0;
for (int i=1; i<=n; ++i) {
for (int j=1; j<=n+1; ++j) c[j]=0;
calc(a, i, b);
if (c[n+1]) return 0;
for (int j=1; j<=n; ++j) c[n+j]=c[j];
for (int j=1; j<=n*2; ++j) h[j]=h[j-1]*base+c[j];
for (int j=1; j<=n; ++j) if (hashing(j, j+n-1)==tem) goto jump;
return 0;
jump: ;
}
//cout<<"loop: "; for (int j=1; j<=n; ++j) cout<<a[j]<<' '; cout<<endl;
return 1;
}
for (int i=0; i<b; ++i) {
a[u]=i;
if (dfs(u+1, b)) return 1;
// dfs(u+1, b);
}
return 0;
}
void solve() {
pw[0]=1;
for (int i=1; i<=n*2; ++i) pw[i]=pw[i-1]*base;
for (int b=x-1; b>1; --b) {
if (dfs(1, b)) {cout<<b<<endl; exit(0);}
// cout<<"test: "<<b<<endl;
// dfs(1, b);
}
puts("-1");
}
}
#endif
namespace task{
bool npri[N];
int pri[N], low[N], lowp[N], pcnt, p, phi;
inline ll qpow(ll a, ll b) {ll ans=1; for (; b; a=a*a%p,b>>=1) if (b&1) ans=ans*a%p; return ans;}
bool isrt(int g) {
for (int t=phi; t>1; t/=lowp[t]) if (qpow(g, phi/low[t])==1) return 0;
return 1;
}
void solve() {
p=n+1;
for (int i=2; i<=p; ++i) {
if (!npri[i]) pri[++pcnt]=low[i]=lowp[i]=i;
for (int j=1,x; j<=pcnt&&i*pri[j]<=p; ++j) {
npri[x=i*pri[j]]=1;
if (!(i%pri[j])) {
low[x]=pri[j];
lowp[x]=lowp[i]*pri[j];
break;
}
else low[x]=lowp[x]=pri[j];
}
}
if (npri[p]) {puts("-1"); exit(0);}
phi=p-1;
for (int i=x-1; i>1; --i) if (isrt(i)) {cout<<i<<endl; exit(0);}
puts("-1");
}
}
signed main()
{
freopen("rotatable.in", "r", stdin);
freopen("rotatable.out", "w", stdout);
n=read(); x=read();
//if (x<=2) puts("-1");
//else if (n==1) cout<<x-1<<endl;
//else if (n<=10) force::solve();
//else cout<<-1<<endl;
task::solve();
return 0;
}