zoukankan      html  css  js  c++  java
  • ACM学习历程—HDU5668 Circle(数论)

    http://acm.hdu.edu.cn/showproblem.php?pid=5668

    这题的话,假设每次报x个,那么可以模拟一遍,

    假设第i个出局的是a[i],那么从第i-1个出局的人后,重新报数到他假设经过了p个人,

    那么自然x = k(n-i)+p(0<= i < n)

    即x = p (mod n-i)

    然后显然可以得到n个这样的方程,于是就是中国剩余定理了。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <vector>
    #include <string>
    #define LL long long
    
    using namespace std;
    
    int n, s[25];
    bool vis[25];
    LL rest[25], mmod[25];
    
    LL gcd(LL a, LL b)
    {
        LL r;
        while (b != 0)
        {
            r = b;
            b = a%b;
            a = r;
        }
        return a;
    }
    
    LL lcm(LL a, LL b)
    {
        return a/gcd(a, b)*b;
    }
    
    //EXGCD
    //求解方程ax+by=d,即ax=d mod(b)
    //扩展可求逆元
    //O(logn)
    void exgcd(LL a, LL b, LL &x, LL &y, LL &d)
    {
        if (b == 0)
        {
            x = 1;
            y = 0;
            d = a;
        }
        else
        {
            exgcd(b, a%b, y, x, d);
            y -= a/b*x;
        }
    }
    
    //中国剩余定理(非互质)
    //其中a为除数数组,n为模数数组
    LL inv(LL a, LL n)
    {
        LL x, y, d;
        exgcd(a, n, x, y, d);
        if (d != 1)
            return -1;
        return (x%n + n) % n;
    }
    
    bool Merge(LL a1, LL n1, LL a2, LL n2, LL &aa, LL &nn)
    {
        LL d = gcd(n1, n2);
        LL c = a2 - a1;
        if (c % d)
            return false;
        //(n1/d)*k1 = (c/d)(mod(n2/d))
        c /= d;
        n1 /= d;
        n2 /= d;
        //k1 = (c/d)*(n1/d)^(-1)(mod(n2/d))
        c *= inv(n1, n2);
        c %= n2;//k1
        c *= n1 * d;//a = n1*k1+a1
        c += a1;
        nn = n1*n2*d;
        aa = c;
        return true;
    }
    
    LL CRT(int len, LL *a, LL *n)
    {
        LL a1 = a[0], n1 = n[0];
        LL a2, n2;
        for (int i = 1; i < len; i++)
        {
            LL aa, nn;
            a2 = a[i], n2 = n[i];
            if (!Merge(a1, n1, a2, n2, aa, nn))
                return -1;
            a1 = aa;
            n1 = nn;
        }
        return (a1%n1 + n1) % n1;
    }
    
    void work()
    {
        LL ans, tmp = 1;
        memset(vis, false, sizeof(vis));
        int now = 0, step, t = 0;
        for (int i = 0; i < n; ++i)
        {
            step = 0;
            for (int j = t%n; j < n; j = (j+1)%n)
            {
                if (vis[j]) continue;
                step++;
                if (j == s[now])
                {
                    now++;
                    vis[j] = true;
                    rest[i] = step%(n-i);
                    mmod[i] = n-i;
                    tmp = lcm(tmp, n-i);
                    t = j;
                    break;
                }
            }
        }
        ans = CRT(n, rest, mmod);
        if (ans == -1)
            printf("Creation August is a SB!
    ");
        else
        {
            ans = (ans%tmp+tmp)%tmp;
            if (ans == 0) ans = tmp;
            cout << ans << endl;
        }
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        int T, u;
        scanf("%d", &T);
        for (int times = 1; times <= T; ++times)
        {
            scanf("%d", &n);
            for (int i = 0; i < n; ++i)
            {
                scanf("%d", &u);
                s[u-1] = i;
            }
            work();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Mysql安装(msi版的安装)
    001 springBoot的数据库操作
    使用IDEA搭建spring
    spring简介
    rabbitMQ的安装(Windows下)
    mysql过滤数据
    mysql查询数据
    均值滤波,中值滤波,最大最小值滤波
    图像运动去模糊(Motion Deblurring)代码
    数字图像处理,图像锐化算法的C++实现
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/5427879.html
Copyright © 2011-2022 走看看