Disgruntled Judge UVA - 12169

题目大意:

对于 f[i] = (f[i-1]*a + b) mod 10001,已知f[1],f[3]……f[n*2-1],求f[2],f[4]……f[n*2]

题目思路:

很明显,我们需要计算a,b的值。很容易得到:(a+1)*b + 10001*(-k) = f[3]-a*a*f[1]

利用扩展欧几里得计算:(a+1)*b0 + 10001*(-k0) = gcd(a+1,10001)

联立方程有:b = b0*(f[3]-a*a*f[1])/gcd(a+1,10001)

将b带入f[],验证是否成立即可

//#pragma GCC optimize(2)
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<stack>
#include<vector>
#include<math.h>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f

LL p[205];

bool Judge(LL a,LL b,LL T)
{
    LL pre = p[1];
    LL now;
    for(int i=2;i<=2*T;i++)
    {
        now = (pre*a + b) % 10001;
        if(i&1 && now != p[i])
            return false;
        pre = now;
    }
    return true;
}

void Exgcd(LL a,LL b,LL &gcd,LL &x,LL &y)
{
    if(!b)
    {
        gcd = a;
        x = 1;
        y = 0;
    }
    else
    {
        Exgcd(b,a%b,gcd,y,x);
        y -= x*(a/b);
    }
}

int main()
{
    LL T;
    while(cin >> T)
    {
        for(int i=1;i<=2*T;i+=2)
            cin >> p[i];

        for(int a=0;;a++)
        {
            LL k,b,gcd,c=p[3]-a*a*p[1];
            Exgcd(a+1,10001,gcd,b,k);
            if(c%gcd !=0 ) continue;
            LL temp = c/gcd;
            b *= temp;
            if(Judge(a,b,T))
            {
                for(int i=2;i<=2*T;i+=2)
                    cout << (a*p[i-1]+b)%10001 << endl;
                break;
            }
        }
    }
    return 0;
}
View Code

 

posted @ 2019-05-02 19:34  声声醉如兰  阅读(192)  评论(0编辑  收藏  举报