Disgruntled Judge
题意
有一个递推公式\(x_i=(a*x_{i-1}+b)mod10001,a<=10000\),然后给出一个T,x从1~2*T,输入x1,x3,x5,........。让输出满足公式的x2,x4,x6......如果有多种答案,输出任意一组。
分析
时限在3s,暴力枚举a,b。
#include<bits/stdc++.h> using namespace std; const int maxn = 1e6; int q[maxn]; int main(void) { int t; cin>>t; for(int i = 1; i <= 2*t; i += 2) cin >> q[i]; bool flag = 0; for(int a = 0; a <= 10000; a++){ for(int b = 0; b <= 10000; b++){ flag = 1; for(int i = 2; i <= 2*t; i++){ if(i%2==0) q[i] = (a*q[i-1]+b)%10001; else{ if(q[i]!=(a*q[i-1]+b)%10001){ flag = 0; break; } } } if(flag) break; } if(flag) break; } for(int i=2; i <= 2*t; i=i+2) cout<<q[i]<<endl; return 0; }
既然a,b都不知道,怎么也得遍历查找一个吧,那就遍历查找a,然后根据递推公式求出b,那怎么求b呢,因为涉及到取模,所以不能直接移项求出.
\[ 对于x_2: x_2=(a*x_1+b)mod10001 \]\[ 对于x_3: x_3=(a*x_2+b)mod10001 \]
两个式子合并一下
\[ x_3=(a*(a*x_1+b)mod10001+b)mod10001 \]\[ x_3=(a*(a*x_1+b)+b)mod10001 \]
\[ x_3+k*10001=a*a*x_1+(a+1)*b. \]
移项得
\[ x_3-a*a*x_1=(a+1)*b+10001*(-k) \]
其中\(和x_3和x_1\)已知,a也已知,就是求b和-k了。#include <bits/stdc++.h> using namespace std; typedef long long ll; ll q[205]; void exgcd(ll a,ll b,ll& d,ll& x,ll& y){ if(!b){ d = a; x = 1; y = 0; }else{ exgcd(b,a%b,d,y,x); y -= x*(a/b); } } int main(void) { int n; cin >> n; for(int i = 1; i <= 2*n; i += 2) cin >> q[i]; for(int a = 0; ; a++){ ll b,k,d; ll c = q[3]-a*a*q[1]; exgcd(10001,a+1,d,k,b); if(c%d) continue; b = b*c/d; int flag = 1; for(int i = 2; i <= 2*n; i++) { if(i%2==0) q[i]=(a*q[i-1]+b)%10001; else{ if(q[i]!=(a*q[i-1]+b)%10001){ flag=0; break; } } } if(flag) break; } for(int i = 2; i <= 2*n; i += 2) cout<<q[i]<<endl; return 0; }