【UVA12169】不爽的裁判

题意

随机选取x1,a,b,根据公式xi=(a*xi-1+b)%10001得到一个长度为2*n的序列,奇数项作为输入,求偶数项,若有多种,随机输出一组答案

即,给出已知的x1,x3,x5,x7……x2k+1,找出a和b,满足递推式,并输出x2,x4,x6……x2k  (n0<=a,b<=10000)

分析

据说暴力也能过???告辞。

题目上说找出a和b这个很像是解方程,于是尝试转换一下条件吧。

x2=(a*x1+b)%10001

x3=(a*x2+b)%10001  ---> x3=(a*((a*x1+b)%10001)+b)%10001

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

将x3看成a*(a*x1+b)+b除以y的余数

则有 x3+y*10001=a*a*x1+a*b+b=a*a*x1+(a+1)*b

再移项 x3-a*a*x1 =(a+1)*b-y*10001 

这个式子是不是很眼熟?假设a为已知,而x1和x3本来就已知,则就是一个关于y和b的二元一次不定方程嘛

用扩展欧几里得求解,需要验证一下x3-a*a*x1是不是gcd(a+1,10001)的倍数

于是枚举a,求出b,再用奇数项验证

代码

  1. #include<bits/stdc++.h>  
  2. using namespace std;  
  3. #define N 1010  
  4. #define mod 10001  
  5. #define RT register   
  6. #define ll long long  
  7. ll n,a,b,y;  
  8. ll xo[N],xe[N];  
  9. template<class T>  
  10. inline void read(T &x)  
  11. {  
  12.     x=0;ll f=1;static char c=getchar();   
  13.     while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}  
  14.     while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}  
  15.     x*=f;  
  16. }  
  17.   
  18. inline ll exgcd(ll a,ll b,ll &x,ll &y)  
  19. {  
  20.     ll ans,t;  
  21.     if(!b)  
  22.     {  
  23.         x=1,y=0;  
  24.         return a;  
  25.     }  
  26.     ans=exgcd(b,a%b,x,y);  
  27.     t=x;x=y;y=t-(a/b)*y;  
  28.     return ans;  
  29. }  
  30.   
  31. inline ll check()  
  32. {  
  33.     memset(xe,0,sizeof(xe));  
  34.     xe[1]=xo[1];  
  35.     for(RT ll i=2;i<=2*n;i++)  
  36.     {  
  37.         xe[i]=(a*xe[i-1]+b)%mod;  
  38.         if((i&1)&&(xo[(i>>1)+1]!=xe[i]))  
  39.             return 0;  
  40.     }  
  41.     return 1;  
  42. }  
  43.   
  44. int main()  
  45. {  
  46.     read(n);  
  47.     for(RT ll i=1;i<=n;i++)read(xo[i]);  
  48.     for(RT ll i=0;i<=10000;i++)  
  49.     {  
  50.         a=i;  
  51.         ll x3=xo[2],x1=xo[1],d=x3-a*a*x1;  
  52.         ll gcd=exgcd(a+1,mod,b,y);  
  53.         if(d%gcd)continue;  
  54.         b=b*d/gcd;  
  55.         if(check())break;  
  56.     }  
  57.     for(RT ll i=2;i<=2*n;i+=2)printf("%lld ",xe[i]);  
  58.     return 0;  
  59.       
  60. }  
原文地址:https://www.cnblogs.com/NSD-email0820/p/9858708.html