您的位置:首页 > 其它

UVA 12169 Disgruntled Judge(Extended_Euclid)

2015-11-13 20:53 204 查看
用扩展欧几里德Extended_Euclid解线性模方程,思路在注释里面了。

注意数据范围不要爆int了。

/*********************************************************
*      --------------Tyrannosaurus---------              *
*   author AbyssalFish                                   *
**********************************************************/
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

/*
取模可以说是个不定方程
如果x3 和 x1满足递推关系,则有
a^2*x1 + (a+1)*b = x3 mod m
(a+1)*b + m * k = x3 - a^2*x1

枚举a,则b和k未知, extended_Euclid
求出一组解 (a+1)*x0 + m*y0 = d
d = gcd(a+1, m)是最小正线性组合,(不包括0,0
对于其他任意的线性组合的和为c, 都是d的倍数,系数(x0 y0)* (c/d)
b在模m意义下唯一

O(T*m)
*/

int ex_euclid(int a, int b, int &x, int &y)
{
if(!b){
x = 1; y = 0;
return a;
}else {
int d = ex_euclid(b, a%b, y, x);
y -= a/b*x;
return d;
}
}

const int mod = 10001, maxn = 105;
int dat[maxn];
int n;

bool check(int a,int &b)
{
int x,y;
int d = ex_euclid(mod, a+1, x, y);
int aa = a*a%mod, c = (dat[1]-aa*dat[0])%mod;
if( (c) % d) return false;
b = c/d*y % mod; //这里要按mod^3算,看见/d自动脑补成了mod^2...
c = (a+1)*b%mod;
for(int i = 1; i < n; i++){
if( (aa*dat[i-1]+c - dat[i])%mod ) {
return false;
}
}
if(b < mod) b += mod;
return true;
}

//#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d",dat+i);
int a, b;
for(a = 0; a < mod; a++){
if(check(a,b)) {
for(int i = 0; i < n; i++){
printf("%d\n", (a*dat[i]+b)%mod);
}
break;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: