Date:2022.04.13 题意描述: 对于 C 语言的循环语句,形如: for (variable = A; variable != B; variable += C) statement; 请问在 k 位存储系统中循环几次才会结束。 若在有限次内结束,则输出循环次数。否则输出死循环。 输入格式 多组数据,每组数据一行四个整数 A,B,C,k。 读入以 0 0 0 0 结束。 输出格式 若在有限次内结束,则输出循环次数。 否则输出 FOREVER。 数据范围 1≤k≤32, 0≤A,B,C<2^k 输入样例: 3 3 2 16 3 7 2 16 7 3 2 16 3 4 2 16 0 0 0 0 输出样例: 0 2 32766 FOREVER
思路:首先k 位存储系统即代表只取最后k位,即
(
a
+
x
?
c
)
%
2
k
=
=
b
%
2
k
(a+x*c)\%2^k==b\%2^k
(a+x?c)%2k==b%2k。
x
?
c
+
y
?
2
k
≡
b
?
a
【
m
o
d
2
k
】
(
I
)
x*c+y*2^k \equiv b-a 【mod 2^k】(I)
x?c+y?2k≡b?a【mod2k】(I) 问题转换为求满足线形同余方程的一个正整数解
x
x
x。
e
x
g
c
d
(
c
,
2
k
,
x
,
y
)
exgcd(c,2^k,x,y)
exgcd(c,2k,x,y)求出
x
?
c
+
y
?
2
k
≡
g
c
d
(
c
,
2
k
)
【
m
o
d
2
k
】
(
I
I
)
x*c+y*2^k \equiv gcd(c,2^k) 【mod2^k】(II)
x?c+y?2k≡gcd(c,2k)【mod2k】(II)。 我们假设
(
I
I
)
(II)
(II)的特解为{
x
0
,
y
0
x_0,y_0
x0?,y0?}。 由此: ①若
g
c
d
(
c
,
2
k
)
?
(
b
?
a
)
gcd(c,2^k)\nmid(b-a)
gcd(c,2k)?(b?a):线性方程组(I)无解。 ②若
g
c
d
(
c
,
2
k
)
∣
(
b
?
a
)
gcd(c,2^k)\mid(b-a)
gcd(c,2k)∣(b?a):线性方程组(I)有解。 其中,一组特解是
(
I
I
)
(II)
(II)的特解扩大若干倍,即:
{
x
1
=
(
b
?
a
)
g
c
d
(
c
,
2
k
)
?
x
0
;
y
1
=
(
b
?
a
)
g
c
d
(
c
,
2
k
)
?
y
0
;
\left\{ \begin{array}{lr} x_1=\frac{(b-a)}{gcd(c,2^k)}*x_0; \\ y_1=\frac{(b-a)}{gcd(c,2^k)}*y_0; \end{array} \right.
{x1?=gcd(c,2k)(b?a)??x0?;y1?=gcd(c,2k)(b?a)??y0?;? 但我们要找
x
>
=
0
x>=0
x>=0,假设找到的是
x
2
x_2
x2?,则
x
2
x_2
x2?必满足:
{
x
2
=
x
1
+
k
?
2
k
g
c
d
(
c
,
2
k
)
;
y
2
=
y
1
?
k
?
c
g
c
d
(
c
,
2
k
)
;
\left\{ \begin{array}{lr} x_2=x_1+k*\frac{2^k}{gcd(c,2^k)}; \\ y_2=y_1-k*\frac{c}{gcd(c,2^k)}; \end{array} \right.
{x2?=x1?+k?gcd(c,2k)2k?;y2?=y1??k?gcd(c,2k)c?;? 我们不妨就求个最小的
x
2
>
0
x_2>0
x2?>0,因此
x
2
(
m
i
n
)
=
x
1
%
2
k
g
c
d
(
c
,
2
k
)
x_{2(min)}=x1\%\frac{2^k}{gcd(c,2^k)}
x2(min)?=x1%gcd(c,2k)2k?,但注意
x
2
x_2
x2?可能为负数,取模为负数,因此
x
2
(
m
i
n
)
=
(
x
1
%
2
k
g
c
d
(
c
,
2
k
)
+
2
k
g
c
d
(
c
,
2
k
)
)
%
2
k
g
c
d
(
c
,
2
k
)
x_{2(min)}=(x1\%\frac{2^k}{gcd(c,2^k)}+\frac{2^k}{gcd(c,2^k)})\%\frac{2^k}{gcd(c,2^k)}
x2(min)?=(x1%gcd(c,2k)2k?+gcd(c,2k)2k?)%gcd(c,2k)2k?。
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N = 55;
typedef long long LL;
LL k,a,b,c;
LL qmi(LL a,LL k)
{
LL res=1;
while(k)
{
if(k&1) res=res*a;
a=a*a;k>>=1;
}
return res;
}
LL exgcd(LL a,LL b,LL &x,LL &y)
{
if(!b)
{
x=1,y=0;
return a;
}
LL d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
int main()
{
while(cin>>a>>b>>c>>k,a||b||c||k)
{
LL x,y,kk=qmi(2,k);
LL d=exgcd(c,kk,x,y);
if((b-a)%d) cout<<"FOREVER\n";
else
{
x*=(b-a)/d;kk/=d;
cout<<(x%kk+kk)%kk<<'\n';
}
}
return 0;
}
|