UVA 12169 不爽的裁判(模算术)

一看就知道是扩展欧几里得,一用就废..

看了看别人的..

说下思路吧,

x2 = (a * x1 + b) % 10001;

x3 = (a * x2 + b) % 10001;

联立2个式子

x3 = (a * (a * x1 + b) % 10001 + b ) % 10001;

x3 = (a * (a * x1 + b) + b) % 10001;

所以x3+10001k= a * (a * x1 + b) % 10001 + b )

x3+10001k+10001k-b=a * (a * x1 + b)

最终:

x3+10001k=a * (a * x1 + b)+b;

(a+1)b -10001k=x3-a²x1

这不就是标准的欧几里得式吗,我们可以通过枚举a,然后算出一个是整数的b,

再通过检验这个b是否使得所有x[i]满足递推公式即可。

#include<bits/stdc++.h>
using namespace std;

typedef unsigned long long ull;
void gcd(ull a,ull b,ull &d,ull &x,ull &y){
    if(!b){d=a;x=1;y=0;return ;}
    else{
    gcd(b,a%b,d,y,x);
    y-=(a/b)*x;
    return ;
    }
}

ull x[205];
int main(){
    
    int t;
    
    scanf("%d",&t);
    for(int i=1;i<=2*t;i+=2)
    scanf("%llu",&x[i]);
    
    ull d,b,k;
    ull value,a;

    for(a=0;a<=10000;a++){
        gcd(a+1,10001,d,b,k);
        int ok=1;
         value=x[3]-a*a*x[1];
        if(value%d) continue;
        
        b=b*value/d;
        
        for(int i=2;i<=2*t;i++){
            if(i&1){                
                if(x[i]!=((a*x[i-1]+b)%10001)){
                    ok=0;
                    break;
                }
                
            }    
            else
            {
                x[i]=(x[i-1]*a+b)%10001;
                
            }
            
        }
        if(ok)
        break;            
    }
        
    for(int i=2;i<=2*t;i+=2)
    printf("%llu\n",x[i]);    
    
    
}

发布了57 篇原创文章 · 获赞 58 · 访问量 648

猜你喜欢

转载自blog.csdn.net/weixin_43568895/article/details/103581778