您的位置:首页 > 其它

uva12169(暴 || 扩展欧几里得)

2018-02-03 22:01 337 查看
题意:已知xi=(a*xi-1+b) mod 10001,且告诉你x1,x3.........x2*t-1,让你求出其偶数列

一种暴力枚举a和b

一种枚举a然后通过扩展欧几里得求b

思路:

枚举a,然后通过x1,x3求出b,再验证是否合适

1.设a, b, c为任意整数。若方程ax+by=c的一组整数解为(x0,y0),则它的任

意整数解都可以写成(x0+kb', y0-ka'),其中a'=a/gcd(a,b),b'=b/gcd(a,b),k取任意整数。

2.设a, b, c为任意整数,g=gcd(a,b),方程ax+by=g的一组解是(x0,y0),则

当c是g的倍数时ax+by=c的一组解是(x0c/g, y0c/g);当c不是g的倍数时无整数解。

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);
x3 - a*a*x1已知,就转化成ax+by = c  /*扩展欧几里得,在中途再用②判定是否是整数解即可
#include <iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<streambuf>
#include<string>

using namespace std;
typedef long long ll;
const ll maxn=10000+5;
const ll mod=10001;
ll x[maxn];
int num=0;
void ext_gcd(ll a,ll b,ll& d,ll &x,ll &y)
{
if(!b)
{
x=1;
y=0;
d=a;
return ;
}
else
{
ext_gcd(b,a%b,d,y,x);
y-=x*(a/b);

}
}
int main()
{

ll t,a;
cin>>t;
for(int i=1;i<=t*2;i+=2)
{
cin>>x[i];
}
int ok=1;
for(a=0;a<mod;a++)
{
ll d,b,m,k;
m=x[3]-a*a*x[1];
ext_gcd(mod,a+1,d,k,b);
if(m%d)
continue;
b=(b*m/d);
ok=1;
// cout<<"////"<<a<<"//"<<b<<endl;

for(int i=2;i<=t*2;i++)
{
if(i%2==0)
{
// cout<<"????"<<(a*x[i-1]+b)<<endl;
x[i]= (a*x[i-1]+b)%mod;
}
else
{
if(x[i]!=((a*x[i-1]+b)%mod))
{
ok=0;
// cout<<"----"<<endl;
break;
}
}
}
if(ok)
break;

}
for(int i=2;i<=t*2;i+=2)
cout<<x[i]<<endl;
return 0;
}


b199
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: