POJ 2115 (模线性方程 -> 扩展欧几里得)

来源:互联网 发布:网络教育培训加盟 编辑:程序博客网 时间:2024/06/06 12:50


题意:

for(i=A ; i!=B ;i +=C)循环语句,问在k位操作系统中循环结束次数。

若在有则输出循环次数。

否则输出死循环。


存在这样的情况;i= 65533 ;i<=2;i+= 4;时i = 2;

由模线性方程->扩展欧几里得、


如何求x的最小正解

x = (x%b+b)%b

y = (y%a+a)%a

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <queue>using namespace std;#define MIN INT_MIN#define MAX INT_MAX#define N 204#define LL __int64LL int gcd(LL n,LL m){    LL  r;    while(m!=0)    {        r = n%m;        n = m;        m = r;    }    return n;}void exgcd(LL a,LL b,LL &x1,LL &y1){     if(b==0)       {              x1=1;              y1=0;              return ;    }     exgcd(b,a%b,x1,y1);//辗转相除       LL t=x1;       x1=y1;            y1=t-a/b*y1;  //设n%b = a;-> a = n - n/b;       return ;}int main(){    LL a,b,c,k;    while(~scanf("%I64d %I64d %I64d %I64d",&a,&b,&c,&k))    {       // int sum = 0;        if(a==0&&b==0&&c==0&&k==0) break;      /*  for(int i = 1;i<=7;i+=2)        {            sum++;            cout<<i<<' '<<endl;        }*/        //推导过程        //不考虑取余,次数 = (b-a)/c+1        //假设次数x = ((b-a + 1<<k)%(1<<k))/c        //变形为:cx = (b-a + 1<<k)%(1<<k)        //根据小白书,模线性方程 cx = (b-a)%(1<<k)        //故:(cx - (b-a))一定是(1<<k)的倍数,设倍数是y        //变形为扩展欧几里得公式: cx - (1<<k)y = (b-a)        //故:有解的充要条件是 (b-a)% gcd(c,1<<k)==0       LL A,C,x1,y1;       LL B = (LL)1<<k;       A = c; C = b - a;      LL st = gcd(A,B);       //cout<<st<<endl;       if(C%st!=0)        puts("FOREVER");       else       {           exgcd(A,B,x1,y1);           x1 = x1 * (C/st)%B;           x1=(x1%(B/st)+B/st)%(B/st);//注意这里要对B取余          // LL tt = (x1 + (C/st))%(C/st);           cout<<x1<<endl;       }    }    return 0;}

直接ex_gcd

#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#define MIN INT_MIN#define MAX INT_MAXconst int N = 210;typedef long long LL;using namespace std;LL ex_gcd(LL a,LL b,LL &x1,LL &y1){    if(b==0)    {        x1 = 1;        y1 = 0;        return a;    }    LL d  = ex_gcd(b,a%b,x1,y1);    LL t = x1;    x1 = y1;    y1 = t - a/b*y1;    return d;}int main(){    LL a,b,c,k;    while(~scanf("%lld%lld%lld%lld",&a,&b,&c,&k))    {        if(a==0&&b==0&&c==0&&k==0) break;        LL A = c;        LL B = (LL)1<<k;        LL C = b-a;        LL x,y;        LL d = ex_gcd(A,B,x,y);        if(C%d!=0) puts("FOREVER");        else        {            x *= C/d; //注意这里 不用对B取余            x = (x%(B/d)+(B/d))%(B/d);            cout<<x<<endl;        }    }    return 0;}


0 0
原创粉丝点击