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
  • 相关阅读:
    bzoj 2744 朋友圈
    bzoj 3674 可持久化并查集加强版
    3.15 模拟赛
    luogu 4720 【模板】扩展卢卡斯
    洛谷 P1447 [NOI2010]能量采集 (莫比乌斯反演)
    洛谷P2522 [HAOI2011]Problem b (莫比乌斯反演+容斥)
    7-12 与零交换 (25 分)
    理想的正方形(单调队列)
    Flowerpot(单调队列)
    生日礼物(单调队列)
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/10725670.html
Copyright © 2011-2022 走看看