题解 循环

传送门
CF303D Rotatable Number

听说有个 \(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;
}
posted @ 2022-02-24 21:16  Administrator-09  阅读(0)  评论(0编辑  收藏  举报