[2016-03-25][SGU][455][Sequence analysis]

  • 时间:2016-03-25 19:15:59 星期五

  • 题目编号:[2016-03-25][SGU][455][Sequence analysis]

  • 题目大意:给定x0=1,xi+1=(axi1+xi1modb)modc,问第二节循环节的位置

  • 分析:floyd判圈

  • 遇到的问题:可能第一节循环节在2*1e6范围内,但是第二节不在

  1. #include <cstdio>
  2. using namespace std;
  3. typedef long long LL;
  4. LL a,b,c,limit = 2 * 1e6;
  5. inline LL nxt(LL x){
  6. return (a*x + x%b)%c;
  7. }
  8. int main(){
  9. scanf("%I64d%I64d%I64d",&a,&b,&c);
  10. LL x1,x2,v = 0;
  11. x1 = x2 = 1;
  12. do{
  13. x1 = nxt(x1);
  14. x2 = nxt(nxt(x2));
  15. ++v;
  16. }while(v<= limit && x1 != x2);
  17. //超过指定长度没有遇到重复
  18. if(v > limit){
  19. puts("-1");
  20. return 0;
  21. }
  22. //确定起点位置v:把一个指针移动到0点,然后两个指针同时移动,每次移动一步,再次到一起的位置就是循环起点
  23. x1 = 1;v = 0;
  24. while (x1 != x2){
  25. x1 = nxt(x1);
  26. x2 = nxt(x2);
  27. ++v;
  28. }
  29. //确定循环节的长度u:继续往下找,再次找到所经过的步数就是长度
  30. LL u = 1;
  31. x1 = nxt(x1);
  32. while(u + v <= limit && x1 != x2){
  33. x1 = nxt(x1);
  34. ++u;
  35. }
  36. if(u + v <= limit) printf("%I64d\n",v + u);
  37. else puts("-1");
  38. return 0;
  39. }


来自为知笔记(Wiz)


posted on 2016-03-25 20:48  红洋  阅读(100)  评论(0)    收藏  举报

导航