Codeforces Gym 101252D&&floyd判圈算法学习笔记
作者:互联网
一句话题意:x0=1,xi+1=(Axi+xi%B)%C,如果x序列中存在最早的两个相同的元素,输出第二次出现的位置,若在2e7内无解则输出-1。
题解:都不到100天就AFO了才来学这floyd判圈算法。
介绍一下floyd判圈算法:该算法适用于在线性时间复杂度内判断有限自动机、迭代函数、链表中是否有环,求环的起点(即链长)和环长。
可以先这么做:首先从起点S出发,给定两个指针,一个快指针一个慢指针,然后每次快指针走1步,慢指针走2步,直到相遇为止。如果已经到达终点/达到规定步数时仍然没有相遇,说明图中没有符合条件的环。如果相遇了,可以确定进入了环(如图则在M点相遇),接下来就要计算环长和环起点。
计算环长:令其中一个指针一直走下去,记录步数即可,因为其在环内,最终一定会在线性复杂度内再次返回节点M。
计算环起点:令其中一个指针位于M,另一个回到S,然后两者以相同速度推进,相遇的点就是环的起点。
证明:留坑,后序补上。
Codeforces Gym 101252D:显然是一道裸题,上code
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e7; ll a,b,c,s,r,x,y; int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); cin>>a>>b>>c; x=y=1; while(s<N) { s++; y=(a*y+y%b)%c,y=(a*y+y%b)%c; x=(a*x+x%b)%c; if(x==y)break; } if(x!=y){puts("-1");return 0;} while(r<N) { r++; y=(a*y+y%b)%c; if(x==y)break; } if(x!=y){puts("-1");return 0;} s=0,y=1; while(x!=y&&s<N) { s++; y=(a*y+y%b)%c; x=(a*x+x%b)%c; } s+=r; if(x==y&&s<=N)cout<<s; else puts("-1"); return 0; }View Code
标签:判圈,101252D,相遇,Codeforces,环长,floyd,起点,指针 来源: https://www.cnblogs.com/hfctf0210/p/10725670.html