现在的位置: 首页 > 综合 > 正文

模线性方程

2019年08月21日 ⁄ 综合 ⁄ 共 881字 ⁄ 字号 评论关闭

poj2115

大致题意:

对于C的for(i=A ; i!=B ;i +=C)循环语句,问在k位存储系统中循环几次才会结束。

若在有限次内结束,则输出循环次数。

否则输出死循环。

解题思路:

根据题意可得方程:

A+C*X=B (X 再%2^k 就是最后要的结果。)

X=[(B-A) / C]% 2^k

  =[(B-A) % 2^k] / C  (C 不需要%,因为
 (0 <= A, B, C < 2
k

  =[(B-A)+2^k]%2^k /C

CX=[(B-A)+2^k]%2^k     (说明 (B-A)与CX 关于 2^k 同余)

所以  CX - (B-A) 是 2^k 的整数倍  PS:因为两个%它 余数相同的话,,两个相减就把余数减掉了!

所以得到方程:

C*X+Y*2^k=(B-A)    PS:(Y是倍数,X即为所求)

解法就很清晰了!

先用 exgcd 求出一组解,然后再模一下 求出 最小解就ok了!

FOREVER 的情况就是(B-A)%gcd 不是整数的情况。。即无限循环!!

//Accepted	132K	0MS	C++	646B	
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
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);}
}
ll mod(ll a,ll b,ll n)
{
    ll d,x,y,l;
    exgcd(a,n,d,x,y);
    if(b%d!=0) return -1;
    x*=b/d;
    l=n/d;
    x=(x%l+l)%l;
    return x;
}
int main()
{
    ll A,B,C,k;
    while(~scanf("%I64d%I64d%I64d%I64d",&A,&B,&C,&k))
    {
        if(A==0&&B==0&&C==0&&k==0) break;
        ll flag;
        flag=mod(C,B-A,1LL<<k);
        if(flag==-1)printf("FOREVER\n");
        else printf("%I64d\n",flag);
    }
    return 0;
}
【上篇】
【下篇】

抱歉!评论已关闭.