hdu5351
题目名称:MZL's Border
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5351
题意:给出fib 1 = b,fib2 = a ; fib i = fib i-1 fib i-2 ,这个递推关系,比如。fib 3 = ab,fib 4 = aba 然后说了一大堆东西,事实上就是要我们求前m个字母中满足 i < n , s [ 1 : i ]=s [ n - i - 1 : n ] 。( s [ 1 : i ]表示串 s 的子串s1s2s3s4s4...si ) 的 i 的最大值
思路:看到这道题是不是自然而然的就想到了KMP。对,一開始我用KMP准备把最大的那个串给保存在next数组里面,因为该串是斐波拉切增长的,,所以数组爆了,然后这道题每一次是把上一个串加到后面,所以想到了打表找规律。0 0 | 1 1 | 2 3 2 3 | 4 5 6 4 5 6 | 7 8 9 10 11 7 8 9 10 11 | 12 13 14 15 16 17 18 19 12 13 14 15 16 17 18 19 这样是不是规律就出来了啊==。然后还得用高精度==。因为JAVA 的高精度比較easy写,以下给出JAVA的代码
代码例如以下:
import java.math.BigInteger; import java.util.Scanner; public class Main { public static void main(String[] args){ Scanner in=new Scanner(System.in); int t; while(in.hasNext()) { t=in.nextInt(); for(int pp=0;pp<t;pp++) { BigInteger n,m,sum=BigInteger.ONE; BigInteger cnt=BigInteger.ZERO; BigInteger ss[] = new BigInteger[3]; ss[1]=BigInteger.ONE;ss[0]=BigInteger.ONE; cnt=new BigInteger("4"); n = in.nextBigInteger(); m = in.nextBigInteger(); BigInteger two = new BigInteger("2"); if(new BigInteger("3").compareTo(m)==1) //m<3 System.out.println("0"); else{ for(;;) { ss[2]=ss[1].add(ss[0]); if(( (cnt.add(ss[2].add(ss[2]))).compareTo(m) ) ==1) //cnt+ss[2]*2>m break; cnt=cnt.add(ss[2].add(ss[2])); //cnt=cnt+ss[2]*2 sum=(sum.add(ss[2])).mod(new BigInteger("258280327")); //sum=(sum+ss[2])%258280327 ss[0]=ss[1]; ss[1]=ss[2]; } if(m.subtract(cnt).compareTo(ss[2])==1) System.out.println( (m.subtract(ss[2]).add(sum).subtract(cnt)).mod(new BigInteger("258280327"))); else System.out.println( (m.add(sum).subtract(cnt) ) .mod(new BigInteger("258280327"))); // if(m-cnt>ss[2]) // cout<<(m-ss[2]+sum-cnt)%258280327<<endl; // else // cout<<(m+sum-cnt)%258280327<<endl; // } } } } } }