POJ2115-C Looooops【扩欧,同余】

正题

链接:
http://poj.org/problem?id=2115


大意

就是给出个循环

for(i=A;i!=B;i=(i+C)mod2k) f o r ( i = A ; i ! = B ; i = ( i + C ) m o d 2 k )

求需要循环次数


解题思路

我们定义 l=2k l = 2 k
首先可以推出:

Cx+AB(modl) C x + A ≡ B ( m o d l )

然后解mod

Cx+A=B+lk C x + A = B + l k

然后定义 y=l y = − l ,移项

Cx+ly=BA C x + l y = B − A

然后我们定义 d=gcd(C,l) d = g c d ( C , l ) ,之后同时除去d

Cx/d+ly/d=(AB)/d C x / d + l y / d = ( A − B ) / d

因为d是C和l的最大公约数那么因为 C C %d=0, l l %d=0,所以只要 (AB) ( A − B ) % d=0 d = 0 这个方程就有解
之后因为这样求出的x不是最大解所以我们要:
定义 g=(l/d) g = ( l / d )
然后

(x((BA)/d) ( x ∗ ( ( B − A ) / d ) % g+g) g + g ) % g g <script type="math/tex" id="MathJax-Element-28">g</script>

求出最小解


代码

#include<cstdio>
using namespace std;
long long x,y,d,a,b,c,k;
long long gcdup(long long a,long long b)
{
    if (b==0)
    {x=1;y=0;return a;}
    d=gcdup(b,a%b);
    long long k=x;
    x=y;
    y=k-a/b*y;
    return d;
}
int main()
{
    while (true)
    {
        scanf("%lld%lld%lld%lld",&a,&b,&c,&k);
        if (a==0 && b==0 && c==0 && k==0) break;
        k=1ll<<k;
        d=gcdup(c,k);
        if ((b-a)%d) printf("FOREVER\n");
        else printf("%lld\n",(x*((b-a)/d)%(k/d)+(k/d))%(k/d));
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值