SGU 455 Sequence analysis(Cycle detection,floyd判圈算法)
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=455
Due to the slow 'mod' and 'div' operations with int64 type, all Delphi solutions for the problem 455 (Sequence analysis) run much slower than the same code written in C++ or Java. We do not guarantee that Delphi solution exists.
You are given a sequence of signed 64-bit integers defined as follows:
- x0 = 1,
,
where
mod
is a remainder operator. All arithmetic operations are evaluated without overflow checking. Use standard "remainder" operator for programming languages (it differs from the mathematical version; for example in programming, while
in mathematics). Use "
long long
" type in C++, "
long
" in Java and "
int64
" in Delphi to store xi and all other values.
Let's call a sequence element xp repeatable if it occurs later in the sequence — meaning that there exists such q, q > p, that xq = xp. The first repeatable element M of the sequence is such an element xm that xm is repeatable, and none of the xp where p < m are repeatable.
Given A, B and C, your task is to find the index of the second occurence of the first repeatable element M in the sequence if the index is less or equal to 2 · 106. Per definition, the first element of the sequence has index 0.
The only line of input contains three signed 64-bit integers: A, B and C (B > 0, C > 0).
Print a single integer — the index of the second occurence of the first repeatable member if it is less or equal to 2 · 106. Print -1 if the index is more than 2 · 106.
题目大意:给出x[0] = 1,还有A、B、C,有x[i+1] = (A * x[i] + x[i] % B) % C。求第二个循环节出现的位置。
思路:http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare (floyd判圈算法,龟兔算法?)
给一个初始值x[0],有一个函数x[i + 1] = f(x[i])。若x始终在有限集合中运算,那么这些x值会构成一个环。
在此题中,整数模一个C后,显然得到的值是有限的。
设第一个循环节从x[μ]开始,循环节长度为λ。
那么对任意i = kλ ≥ μ,一定会有x[kλ] = x[kλ + kλ],即x[i] = x[2i]。
于是我们可以用以下代码,找出满足x[v] = x[2v]的第一个ν,显然在[μ, μ + λ]间存在一个v = kλ,则此步复杂度为O(μ+λ)。
long long x = f(x0), y = f(f(x0));
int v = 1;
while(x != y)
x = f(x), y = f(f(y)), v++;
由于对任意i ≥ μ,有x[i] = x[i + λ] = x[i + kλ],那么同意有x[μ] = x[μ + λ] = x[μ + kλ] = x[μ + v]。
在上面的代码中,我们已经求得了x[v],其中两个变量都等于x[v]。
那么基于x[μ] = x[μ + v]的事实。我们可以用下面的代码,循环μ次,求出x[μ]。
x = x0;
int mu = 0;
while(x != y)
x = f(x), y = f(y), mu++;
上述代码已经求出μ与x[μ]。最后,只要再循环λ遍,即可求出循环节长度:
int lam = 1;
y = f(x);
while(x != y) y = f(y), lam++;
总时间复杂度为O(μ+λ),空间复杂度为O(1)。
对于本题,输出μ+λ即可。
至于本题的计算过程可能溢出的事情我没想……我发现大家都没管,我也不管了……
代码(312MS):
#include <bits/stdc++.h>
using namespace std;
typedef long long LL; const int MAXR = 2e6; LL A, B, C; LL next(LL x) {
return (A * x + x % B) % C;
} int main() {
scanf("%I64d%I64d%I64d", &A, &B, &C);
LL x = next(), y = next(x);
int v = ;
while(v <= MAXR && x != y)
x = next(x), y = next(next(y)), v++;
if(v > MAXR) {
puts("-1");
return ;
} x = ;
int mu = ;
while(x != y)
x = next(x), y = next(y), mu++; int lam = ;
y = next(x);
while(mu + lam <= MAXR && x != y) y = next(y), lam++; if(mu + lam <= MAXR) printf("%d\n", mu + lam);
else puts("-1");
}
SGU 455 Sequence analysis(Cycle detection,floyd判圈算法)的更多相关文章
- Floyd判圈算法 Floyd Cycle Detection Algorithm
2018-01-13 20:55:56 Floyd判圈算法(Floyd Cycle Detection Algorithm),又称龟兔赛跑算法(Tortoise and Hare Algorithm) ...
- Floyd判圈算法
Floyd判圈算法 leetcode 上 编号为202 的happy number 问题,有点意思.happy number 的定义为: A happy number is a number defi ...
- leetcode202(Floyd判圈算法(龟兔赛跑算法))
Write an algorithm to determine if a number is "happy". 写出一个算法确定一个数是不是快乐数. A happy number ...
- Floyd 判圈算法
Floyd 判圈算法 摘自维基百科, LeetCode 上 141题 Linked List Cycle 用到这个, 觉得很有意思. 记录一下. 链接: https://zh.wikipedia.or ...
- UVA 11549 CALCULATOR CONUNDRUM(Floyd判圈算法)
CALCULATOR CONUNDRUM Alice got a hold of an old calculator that can display n digits. She was bore ...
- UVA 11549 Calculator Conundrum (Floyd判圈算法)
题意:有个老式计算器,每次只能记住一个数字的前n位.现在输入一个整数k,然后反复平方,一直做下去,能得到的最大数是多少.例如,n=1,k=6,那么一次显示:6,3,9,1... 思路:这个题一定会出现 ...
- Codeforces Gym 101252D&&floyd判圈算法学习笔记
一句话题意:x0=1,xi+1=(Axi+xi%B)%C,如果x序列中存在最早的两个相同的元素,输出第二次出现的位置,若在2e7内无解则输出-1. 题解:都不到100天就AFO了才来学这floyd判圈 ...
- Floyd判圈算法 UVA 11549 - Calculator Conundrum
题意:给定一个数k,每次计算k的平方,然后截取最高的n位,然后不断重复这两个步骤,问这样可以得到的最大的数是多少? Floyd判圈算法:这个算法用在循环问题中,例如这个题目中,在不断重复中,一定有一个 ...
- UVa 11549 计算器谜题(Floyd判圈算法)
https://vjudge.net/problem/UVA-11549 题意: 有一个老式计算器,只能显示n位数字,输入一个整数k,然后反复平方,如果溢出的话,计算器会显示结果的最高n位.如果一直这 ...
随机推荐
- osg中遇到的问题
osg中遇到的问题 今天写程序的时候, 需要把键盘和鼠标消息转发出来, 就直接写了接口用signal丢出来了. 程序写的很多, 测试的时候却崩溃了.... 在场景中拖拽鼠标左键的时候, 会发现在扔出鼠 ...
- Jquery_jquery中attr和prop的区别
在高版本的jquery引入prop方法后,什么时候该用prop?什么时候用attr?它们两个之间有什么区别?这些问题就出现了. 关于它们两个的区别,网上的答案很多.这里谈谈我的心得,我的心得很简单: ...
- [LintCode] Surrounded Regions 包围区域
Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is captured ...
- hdu Code Lock
题意是说有N个字母组成的密码锁, 如[wersdfj], 每一位上的字母可以转动, w可转动变成x, z变成a.但是题目规定, 只能同时转动某个区间上的所有字母, 如[1,3], 那么第1到第3个 ...
- windows自带的压缩,解压缩命令
压缩一个文件: makecab c:\ls.exe ls.zip 解压一个文件: expand c:\ls.zip c:\ls.exe
- Hibernate配置Log4J,很有参考价值的
hibernate3 自带的默认的日志框架是slf4j,hibernate3的slf只是一个日志的接口,而hibernate3 自带默认的日志框架,在实际开发中很少有公司或者是项目中用到,这里记录一种 ...
- Algorithm | Tree traversal
There are three types of depth-first traversal: pre-order,in-order, and post-order. For a binary tre ...
- Cookie案例-显示商品浏览历史纪录
package cn.itcast.cookie; import java.io.IOException; import java.io.PrintWriter; import java.util.D ...
- ios-系统警告框 跳转到设置里面
-(void)createUIAlertIphone:(NSString*)title { UIAlertController * alert =[UIAlertController alertCon ...
- SaveData Functions
Here are some save function for some situations: Yes/No /// <summary> ///保存数据到WCF /// </sum ...