题意
给一个长度为(200)的(01)串,判断是否是序列({x_i | x_i=|mu(i)|,1le ile10^9})的一部分。若是,输出开头数字的最小值。
思路
由莫比乌斯函数的性质可以发现(x≡0pmod{4})的莫比乌斯函数为(0),对(9),(25),(49),(121),(169)同理,所以可以通过判断(200)个数中(0)的情况,可以取得一个第一个数的备选集((x≡a_1pmod{4}),(x≡a_2pmod{9}),(x≡a_3pmod{25}),(x≡a_4pmod{49}),(x≡a_5pmod{121}),(x≡a_6pmod{169}),可以通过中国剩余定理算出),然后对(x_1dots x_{200})每个数判断是否是正确的莫比乌斯函数值
代码
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
int mod[6]={4,9,25,49,121,169};
const ll M=901800900;
ll mpow(ll a,ll b,ll mod)
{
ll ans=1;
while(b)
{
if(b&1)ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
int crt(int a[6])
{
int ans=0;
for(int i=0;i<6;i++)
{
ll m=M/mod[i];
ll m1=mpow(m,mod[i]*mod[i]-mod[i]-1,mod[i]);
ans=(ans+a[i]*m*m1)%M;
}
return ans;
}
string str;
const int maxp=1e9-199;
vector<int>p[6];
int re[6];
ll ans=1e9;
const int maxn=4e4+5;
int prime[maxn],pcnt;
void init(int n=maxn-1)
{
for(int i=2;i<=n;i++)
{
if(!prime[i])
prime[++pcnt]=i;
for(int j=1;j<=pcnt,prime[j]*i<=n;j++)
{
prime[prime[j]*i]=1;
if(i%prime[j]==0)
break;
}
}
}
int absu(int x)
{
for(int i=1;i<=pcnt;i++)
{
int pp=prime[i]*prime[i];
if(pp>x)
break;
if(x%pp==0)
return 0;
}
return 1;
}
bool check(int p)
{
vector<int>ans(200,1);
for(int i=1;i<=pcnt;i++)
{
int pp=prime[i]*prime[i];
for(int j=(prime[i]-1+p)/prime[i]*prime[i];j<p+200;j+=prime[i])
{
if(j%pp==0)
ans[j-p]=0;
}
}
for(int i=0;i<200;i++)
{
if(ans[i]!=str[i]-'0')
return false;
}
return true;
}
void dfs(int i)
{
if(i<0)
{
ll p=crt(re);
while(p<=maxp)
{
if(check(p))
{
ans=min(ans,p);
break;
}
p+=M;
}
return;
}
for(int x:p[i])
{
re[i]=x;
dfs(i-1);
}
}
void solve(){
string tmp;
str="";
for(int i=0;i<10;i++)
{
cin>>tmp;
str+=tmp;
}
int cnt=0;
for(int i=0;i<200;i++)
cnt+=str[i]-'0';
if(cnt<100) //剪枝
{
cout<<"-1
";
return;
}
bool has=true;
for(int i=0;i<6;i++)
{
p[i].clear();
for(int j=0;j<mod[i];j++)
{
bool flag=true;
for(int k=j;k<200;k+=mod[i])
{
if(str[k]=='1')
{
flag=false;
break;
}
}
if(flag)
p[i].push_back((mod[i]-j)%mod[i]);
}
if(p[i].empty())
has=false;
}
if(has)
{
dfs(5);
if(ans<(1e9))
cout<<ans<<"
";
else
cout<<"-1
";
}
else
cout<<"-1
";
}
int main()
{
init();
ios::sync_with_stdio(false);
int T=1;
// cin>>T;
for(int i=1;i<=T;i++)
solve();
return 0;
}