题意:
看白书
要点:
再一个办法就是枚举a,利用x1,x3求出b,判断所有x的关系能不能满足a,b。
如何通过a,x1,x3求出b呢。
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 + 10001 * k = a * a * x1 + (a + 1) * b; x3 - a * a * x1 = (a + 1) * b + 10001 * (-k);这样就成了求 b 和 -k,满足这个式子,就是扩展欧几里得的一般用法
这是理论分析,然后实际做题中我WA了一次,TLE了一次,WA的原因是a我看错题了,题目中没有给定a的范围,我以为也是0~10000。TLE的原因是我一开始想直接用x[i]和x[I-2]判断b是否成立,感觉也没慢到那去,但就是TLE了,没办法只能按别人的来。
#include#include #include #define ll long longint x[500];ll gcd(ll a, ll b, ll &x, ll &y){ if (!b) { x = 1; y = 0; return a; } ll ans=gcd(b, a%b, x, y); ll temp = x; x = y; y = temp - a / b*y; return ans;}int main(){ int n,i; ll a, t; scanf("%d", &n); for (i = 1; i <=2*n; i+=2) scanf("%d", &x[i]); ll xx, yy; for (a = 0;; a++) { ll d = gcd(10001, -(a + 1), xx, yy); ll t = a*a*x[1] - x[3]; if (t%d != 0) continue; //不能整除直接无解 yy *= t/d; bool flag = true; for (i = 2; i <= 2 * n; i++) { if (i & 1) //同位与,相当与取奇数 { if (x[i] != (a*x[i - 1] + yy) % 10001) { flag = false; break; } } else x[i] = (a*x[i - 1] + yy) % 10001; } if (flag) break; } for (i = 2; i <= 2*n; i+=2) printf("%lld\n",x[i]); return 0;}