Doom
比赛的时候没有做出来,补题。
题意:题目定义了一个斐波那契串
1) fib1=b;
2) fib2=a;
3) fibi=fibi-1fibi-2,i>2
举例,fib3=ab,fib4=aba,fib5=abaab
我们暂时将字符串sisi+1si+2si+3…sj记做s[i:j]
求满足s[1:i]=s[m-i+1:m](i<m)的i的最大值,记做LBorderm
例如m=5时,LBorderm=2,因为abaab中前两个和末尾两个相同,即黑色部分
解题思路:
一看到题目的数据这么大,理所当然就会想到必定存在规律,先列出几项观察一下
m LBorderm D-value(差值)
1 0 1
2 0 2
3 1 2
4 1 3
5 2 3
6 3 3
7 2 5
8 3 5
9 4 5
10 5 5
11 6 5
12 4 8
13 5 8
14 6 8
由上述例子可知,m与结果之间的差值是斐波那契数,仔细观察一下,便会得出这样一个结论:
当我们找到第一个i满足m+1<|fibi|时,LBorderm=m-|fibi-2|(|fibi-2|表示斐波那契串fibi-2的长度)
1 import java.util.*; 2 import java.io.*; 3 import java.math.*; 4 5 public class Main { 6 public static Scanner cin = new Scanner(new BufferedInputStream(System.in)); 7 public final static int MS = 1005; 8 public final static BigInteger MOD = new BigInteger("258280327"); 9 public final static BigInteger[] fib = new BigInteger[MS]; 10 static { 11 fib[1] = BigInteger.ONE; 12 fib[2] = new BigInteger("2"); 13 for(int i = 3; i < MS; i++) 14 fib[i] = fib[i - 1].add(fib[i - 2]); 15 } 16 public static void main(String[] args) { 17 int T, n; 18 BigInteger m; 19 T = cin.nextInt(); 20 while (T-- > 0) { 21 n = cin.nextInt(); 22 m = cin.nextBigInteger(); 23 m.add(BigInteger.ONE); 24 for (int i = 1; i < MS; i++) { 25 if (fib[i].compareTo(m) > 0) { 26 System.out.println(m.subtract(fib[i - 2]).mod(MOD)); 27 break; 28 } 29 } 30 } 31 } 32 }