CSU - 1597 薛XX后代的IQ

41 篇文章 0 订阅
32 篇文章 0 订阅

我尊敬这题,也鄙视我自己.
这题一开始看到没有思路,因为我每次看到这种大计算,只知道快速幂,当然几乎每次都没用.
然后发现这题x,y,p都是300以内的,也就是说,在10^18次方内,x,y最多也只有90000种组合,这是很少的,所以我们可以直接全部算出来,显然会在某一个地方陷入循环,那么然后就算再多的后代,也可以取模取掉.
这思路是很简单的,但我犯了两个致命失误,这题wa了很久.
1.认为循环会从头开始,这是一个错误的潜意识,认为每组数据的循环都是刚好从头部开始,最可怕的是题目给的四组样例也全都是从头开始的循环.
2.没有画图,很多时候一个加一减一不对,就wa了.
如果你没有理解我的话,把我代码里的注释打开,就行了.

/*  xzppp  */
#include <iostream>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <list>
#include <math.h>
#include <iomanip>
using namespace std;
#define FFF freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define MP make_pair
typedef long long  LL;
typedef unsigned long long ULL;
const int MAXN = 400;
const int  INF = 0x7fffffff;
const int MOD = 1e9+7;
LL all[MAXN+17][MAXN+17];
int main()
{
   //   FFF
    int t;
    cin>>t;
    while(t--)
    {
        LL x,y,a,b,p,n;
        cin>>x>>y>>a>>b>>p>>n;
        memset(all, -1, sizeof(all));
        vector<pair<pair<LL,LL > ,LL > > ans;
        ans.clear();
        if(x==y&&a==b)
        {
            cout<<0<<endl;
            continue;
        }
        while(1)
        {
            if(all[x][y]!=-1)
                break;
            else
            {
                all[x][y] = (x*a+y*b)%p;
                int temp = all[x][y];
                ans.push_back(MP(MP(x,y),temp));
                //cout<<x<<" "<<" "<<y<<" "<<temp;//可以用这行注释来进行打表,增强题目理解.
                x = y;
                y = temp;
            }
        }
        int plc;
        for (int i = 0; i <ans.size(); ++i)
            if(ans[i].second==all[x][y]&&x==ans[i].first.first&&y==ans[i].first.second)
            {
                plc = i;
                break;
            }
        if(n>plc)
            cout<<ans[plc+(n-plc-1)%(ans.size()-plc)].second<<endl;
        else
            cout<<ans[n-1].second<<endl;
    }   
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值