关闭

poj2115

153人阅读 评论(0) 收藏 举报
分类:

循环多少次

题目描述:

题意:for(int i = a; i != b; i = (i + c) % (2 ^ k)) 能运行多少次

题解:

其实就是求 ax+by=c,x的最小整数解.

重点:

解的标准步骤:先gcd(a,b),之后同时除以.保证a和b互质.之后求ax+by=1,求出来x之后先%b搞的小一点,之后重点:x*c,之后模的还是b.重点是之后模的还是b

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <ctype.h>
#include <limits.h>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
#define CLR(a) memset(a, 0, sizeof(a))
#define REP(i, a, b) for(ll i = a;i < b;i++)
#define REP_D(i, a, b) for(ll i = a;i <= b;i++)

typedef long long ll;

using namespace std;

ll a, b, c, k, m;

ll gcd(ll a, ll b)
{
    if(b==0)
        return a;
    return gcd(b, a%b);
}
ll ext_gcd(ll a, ll b, ll &x, ll &y)
{
    if(b==0)
    {
        x = 1;
        y = 0;
        return a;
    }
    ll res = ext_gcd(b, a%b, x, y);
    ll t = x;
    x = y;
    y = t - a/b*y;
    return res;
}

void solve()
{
    m = ((1LL) << k);
    ll C = (c - a)%m + m;
    C %= m;
    ll A = b;
    ll B = m;
    ll d = gcd(A, B);
    if(C%d==0)
    {
        A /= d;//先除以gcd
        B /= d;
        C /= d;
        ll x, y;
        ext_gcd(A, B, x, y);
       // x = (x*C/d)%m;
       // x = (x%(B/d)+B/d)%(B/d);
        x = (x%B + B)%B;//x先模b
        x = (x*C);//*c
        x = (x%B + B)%B//模的还是b;
       // x = x%(B*C);
        printf("%I64d\n", x);
    }
    else
    {
        printf("FOREVER\n");
    }
}

int main()
{
   // freopen("3Cin.txt", "r", stdin);
    //freopen("3Cout.txt", "w", stdout);
    while(scanf("%I64d%I64d%I64d%I64d", &a, &c, &b, &k)&&k!=0)
    {
        solve();
    }
    return 0;
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:43229次
    • 积分:2402
    • 等级:
    • 排名:第15446名
    • 原创:206篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    最新评论