zoukankan      html  css  js  c++  java
  • HDU 5351 MZL's Border (规律,大数)

    [HDU 5351 MZL's Border]
    题意
      定义字符串$f_1=b,f_2=a,f_i=f_{i-1}f_{i-2}$。

      对$f_n$的长度为$m$的前缀$s$,

      求最大的$k$满足$s[1]=s[m-k+1],s[2]=s[m-k+2]...s[k]=s[m]$

     


     

    Solution

      先列出前几个字符串

      $f_3=ab,f_4=aba,f_5=abaab,f_6=abaababa,f_7=abaababaabaab$。

      对于n,m。

      假设$f_{n-1}$的长度大于等于$m$,那么相当于求n-1,m。

      假设$f_{n-1}$的小于$m$

      由斐波那契的性质,答案要么是$m-length(f_{n-1})$,

      要么是$m-length(f_{n-2})$

      通过对前几个字符串的分析可以发现,当$m+1<length(f_n)$时答案是后者。

      于是只要先把前1000个字符串的长度求出来。需要使用高精度。

      然后直接按照上面的规则判断就行了。

     

    #include <bits/stdc++.h>
    #define lson x << 1
    #define rson x << 1 | 1
    #define LL long long
    #define se second
    #define fi first
    #define LL long long
    using namespace std;
    
    const int N = 1003;
    
    string  fib[N], m, ans;
    
    inline string add ( string a, string b )
    {
        if ( a.size() < b.size() ) swap ( a, b );
        int la = a.size(), lb = b.size(), x = 0, i = 0;
        for ( i = 0; i < lb; ++i ) {
            x += ( a[i] - '0' + b[i] - '0' );
            a[i] = '0' + x % 10;
            x /= 10;
        }
        while ( x && i < la ) {
            x += ( a[i] - '0' );
            a[i] = '0' + x % 10;
            x /= 10;
            ++i;
        }
        if ( x ) a += '0' + x;
        return a;
    }
    
    inline string sub ( string a, string b )
    {
        int la = a.size(), lb = b.size(), x = 0, i = 0;
        for ( i = 0; i < lb; ++i ) {
            if ( a[i] - x >= b[i] ) {
                a[i] = a[i] - x - b[i] + '0';
                x = 0;
            } else {
                a[i] = 10 + '0' + a[i] - b[i] - x;
                x = 1;
            }
        }
        while ( x && i < la ) {
            if ( a[i] != '0' ) {
                a[i] = a[i] - 1;
                x = 0;
            } else {
                a[i] = '9';
                ++i;
            }
        }
        i = la - 1;
        while ( a[i] == '0' && i != 0 ) {
            a.erase ( a.begin() + i );
            --i;
        }
        return a;
    }
    
    int T, n;
    
    inline bool pd ( string a, string b )
    {
        if ( a.size() == b.size() )  {
            for ( int i = a.size() - 1; i >= 0; --i ) {
                if ( a[i] != b[i] ) return a[i] > b[i];
            }
            return 0;
        }
        return a.size() > b.size();
    }
    
    void make ( int n, string m )
    {
        if ( n < 4 ) {
            ans = "0";
            return ;
        }
        if ( pd ( m, fib[n - 1] ) ) {
            string s1 = sub ( fib[n], "2" );
            if ( !pd ( m, s1 ) ) {
                ans = sub ( m, fib[n - 2] );
            } else {
                ans = sub ( m, fib[n - 1] );;
            }
            return ;
        } else make ( n - 1, m );
    }
    
    void MOD ( string s, LL k )
    {
        LL tem = 0;
        for ( int i = s.size() - 1; i >= 0; --i ) {
            tem = ( tem * 10 + s[i] - '0' ) % k;
        }
        cout << tem << endl;
    }
    int main()
    {
        fib[0] = "0";
        fib[1] = "1";
        for ( int i = 2; i <= 1000; ++i ) {
            fib[i] = add ( fib[i - 1] , fib[i - 2] );
        }
        cin >> T;
        while ( T-- ) {
            cin >> n >> m;
            reverse ( m.begin(), m.end() );
            make ( n, m );
            MOD ( ans, 258280327 );
        }
    }
    View Code

     

  • 相关阅读:
    java接口工厂模式理解
    ViewDragHelper的点击事件处理
    ViewDragHelper的使用
    路径跟踪 PathMeasure的简单使用
    view事件分发源码理解
    layoutInflater参数解析与源码分析
    安卓menu的介绍与使用
    安卓广播api介绍,给自己理清楚概念
    动态删除集合遇到的一些问题理解
    【翻译】借助 NeoCPU 在 CPU 上进行 CNN 模型推理优化
  • 原文地址:https://www.cnblogs.com/keam37/p/4705003.html
Copyright © 2011-2022 走看看