IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【一本通】C循环【exgcd】 -> 正文阅读

[C++知识库]【一本通】C循环【exgcd】

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?2kb?amod2k(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?2kgcd(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;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-14 23:31:36  更:2022-04-14 23:31:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:43:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码