zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    【题解】2020 年电子科技大学 ACMICPC 暑假前集训 数据结构
    【逆向】某触控板驱动分析过程
    SME 2019 ACM 题解
    数据结构 & 算法模板汇总
    VS2010win32下cocos2dx控制台打印的方法
    CDMA写码与鉴权(转载)
    mapxtreme开发小结2(c#)
    LONG GetWindowLong函数功能
    无边框的对话框的大小拖动实现
    YUV介绍
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/10725670.html
Copyright © 2011-2022 走看看