【HDU 1005】 Number Sequence 周期

A number sequence is defined as follows:

f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.

Given A, B, and n, you are to calculate the value of f(n).
Input
The input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed.
Output
For each test case, print the value of f(n) on a single line.
Sample Input
1 1 3
1 2 10
0 0 0
Sample Output
2
5

题意:如题

思路:

暴力的话就别想了(哪怕O(n)),破题口在于余数。看到余数要想到周期,而且这里的取余7这么小,要从这里下手。
考虑A * f(n - 1) + B * f(n - 2),无论f(n-1)还是f(n-2)都只能在0 1 2 3 4 5 6 中取值,那么肯定会有重复的f(n-1)和f(n-2)对出现,而且一旦出现,就一定是一个周期了。显然这样两两配对最多也就49种情况,所以周期不会超过49。我们就对这个范围内扫一遍,看看第一次出现f[n-1] == f[n-2] == 1的地方,就是一个周期过两个了。拿到周期我们就很容易知道n对应的f是谁了。

AC代码:

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };

map<PII,ll> Map;
vector<ll> Mod;
ll f[maxn];

int main()
{
    ll a,b,n;
    while(cin>>a>>b>>n&&(a||b||n))
    {
        f[1] = f[2] = 1; Mod.clear();
        if(n==1||n==2)
        {
            cout<<1<<'\n';
            continue;
        }
        int flag = 0; Mod.pb(1), Mod.pb(1);
        rep(i,3,51)
        {
            if(f[i-2]==1&&f[i-1]==1&&i!=3) break;
            f[i] = (a*f[i-1] + b*f[i-2])%7;
            if(i==n)
            {
                cout<<f[i]<<'\n';
                flag = 1;
                break;
            }

            Mod.pb(f[i]);
        }
        if(!flag)
        {
            ll m = Mod.size() - 2;
            cout<<Mod[(n%m - 1 + m)%m]<<endl;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45492531/article/details/107853496