就是说给你一个序列。第0项是1其余由上一项决定。。
如果第一个与前面的数重复的数的编号小于2000000。。就输出这个编号。。否则就输出-1.。
分析:一开始我当然想的是用hash,set之类的数据结构来搞定。。结果TLE的跟鬼一样。。
后来我在wiki上看到了寻找循环节的O(1)空间算法。。这才恍然大悟。。真的很神奇。
Link:Cycle Finding
简单的介绍一下吧。。设Fx是序列中的第x个数。。弄两个指针。。一个指向Fi。。一个指向F2*i。。
每次讲i加一,那么第一个指针前进1个。第二个前进两个。直到Fi=F2*i了。。i就是一个循环节了。。
然后从第0个数开始推起。。找出第一个x使Fx=Fx+i。。
然后再从x往后推。。找到第一个与其相等的。就是答案了。。
Code:
#include<iostream>
using namespace std;
typedef long long ll;
ll A,B,C;
const int maxn=2e6;
ll next(const ll&x)
{
return (A*x+x%B)%C;
}
void init()
{
cin>>A>>B>>C;
}
bool solve()
{
ll l=next(1),r=next(l);
for(int i=1;i<=maxn+1;i++)
{
if(l==r) break;
l=next(l);
r=next(r);r=next(r);
}
if(l!=r) return false;
l=1;int f=0;
while(l!=r)
{
l=next(l);
r=next(r);
f++;
}
r=next(l);
for(int n=f+1;n<=maxn;n++)
{
if(l==r){cout<<n<<endl;return true;}
r=next(r);
}
return false;
}
int main()
{
init();
if(!solve())cout<<-1<<endl;
}
本高亮代码使用codeHl生成,
sf