时间:2016-03-25 19:15:59 星期五
题目编号:[2016-03-25][SGU][455][Sequence analysis]
题目大意:给定x0=1,xi+1=(a∗xi−1+xi−1modb)modc,问第二节循环节的位置
分析:floyd判圈
遇到的问题:可能第一节循环节在2*1e6范围内,但是第二节不在
#include <cstdio>using namespace std;typedef long long LL;LL a,b,c,limit = 2 * 1e6;inline LL nxt(LL x){ return (a*x + x%b)%c; }int main(){ scanf("%I64d%I64d%I64d",&a,&b,&c); LL x1,x2,v = 0; x1 = x2 = 1; do{ x1 = nxt(x1); x2 = nxt(nxt(x2)); ++v; }while(v<= limit && x1 != x2); //超过指定长度没有遇到重复 if(v > limit){ puts("-1"); return 0; } //确定起点位置v:把一个指针移动到0点,然后两个指针同时移动,每次移动一步,再次到一起的位置就是循环起点 x1 = 1;v = 0; while (x1 != x2){ x1 = nxt(x1); x2 = nxt(x2); ++v; } //确定循环节的长度u:继续往下找,再次找到所经过的步数就是长度 LL u = 1; x1 = nxt(x1); while(u + v <= limit && x1 != x2){ x1 = nxt(x1); ++u; } if(u + v <= limit) printf("%I64d\n",v + u); else puts("-1"); return 0;}