2020暑期牛客多校第五场E.Bogo Sort(环+LCM+大数模版)

题目链接:https://ac.nowcoder.com/acm/contest/5670/E
题意:给出一个固定的置换,问有多少组数组可以通过这个置换得到一个有序的序列(1 2 3 … n)
解题思路:
因为置换是固定的,所以只需要求出一个有序的序列(1 2 3 …n)可以通过多少次置换再次回到原来的样子即可
然后直接求出每个数经过多少次可以回到原来的位置,求出这些次数的公倍数就可以求出总的序列经过多少次可以回到原来,但这样做会超时
可以发现每个数经过的位置是一个循环,每个处于循环中的数都可以经过相同的次数回到原来的位置,所以只需要求出每个环中的一个数需要的次数就可以了,然后求出最小公倍数
PS:因为涉及到大数,所以使用大数模版,而使用的大数模版中没有大数对大数的取模,因为本题取模的是10^n,所以直接取大数的后n位输出即可,不需要取模
大数模版
大数模版

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
#define maxn 100100
#define MAXN 9999
#define MAXSIZE 500   //最大长度
#define DLEN 4
 
class BigNum {
private:
    int a[210000];    //控制大数的位数
    int len;       //长度
public:
    BigNum() { len = 1; memset(a, 0, sizeof(a)); }   //构造函数
    void XD();
    BigNum(const int);
    BigNum(const long long int);
    BigNum(const char*);
    BigNum(const string&);
    BigNum(const BigNum&);  //拷贝构造函数
    BigNum& operator = (const BigNum&);   //重载赋值运算符
    BigNum& operator = (const int&);
    BigNum& operator = (const long long int&);
 
    friend istream& operator >> (istream&, BigNum&);   //重载输入运算符
    friend ostream& operator << (ostream&, BigNum&);   //重载输出运算符
 
    template<typename T> BigNum operator << (const T&) const;
    template<typename T> BigNum operator >> (const T&) const;
 
    BigNum operator + (const BigNum&) const;   //重载加法运算符,大数加大数
    BigNum operator - (const BigNum&) const;   //重载减法运算符,大数减大数
    BigNum operator * (const BigNum&) const;   //重载乘法运算符,大数乘大数
    bool   operator > (const BigNum& b)const;   //重载大于
    bool   operator < (const BigNum& b) const;   //重载小于
    bool   operator == (const BigNum& b) const;  //重载等于符号
    template<typename T> BigNum operator / (const T&) const;    //重载除法运算符,大数除整数
    template<typename T> BigNum operator ^ (const T&) const;    //大数的n次方
    template<typename T> T    operator % (const T&) const;    //大数对int取模
 
    template<typename T> BigNum operator + (const T& b) const { BigNum t = b; t = *this + t; return t; }
    template<typename T> BigNum operator - (const T& b) const { BigNum t = b; t = *this - t; return t; }
    template<typename T> BigNum operator * (const T& b) const { BigNum t = b; t = (*this) * t; return t; }
    template<typename T> bool   operator < (const T& b) const { BigNum t = b; return ((*this) < t); }
    template<typename T> bool   operator > (const T& b) const { BigNum t = b; return ((*this) > t); }
    template<typename T> bool   operator == (const T& b) const { BigNum t = b; return ((*this) == t); }
 
    bool   operator <= (const BigNum& b) const { return (*this) < b || (*this) == b; }
    bool   operator >= (const BigNum& b) const { return (*this) > b || (*this) == b; }
    bool   operator != (const BigNum& b) const { return !((*this) == b); }
 
    template<typename T> bool   operator >= (const T& b) const { BigNum t = b; return !((*this) < t); }
    template<typename T> bool   operator <= (const T& b) const { BigNum t = b; return !((*this) > t); }
    template<typename T> bool   operator != (const T& b) const { BigNum t = b; return !((*this) == t); }
 
    BigNum& operator += (const BigNum& b) { *this = *this + b; return *this; }
    BigNum& operator -= (const BigNum& b) { *this = *this - b; return *this; }
    BigNum& operator *= (const BigNum& b) { *this = *this * b; return *this; }
    template<typename T> BigNum& operator /= (const T& b) { *this = *this / b; return *this; }
    template<typename T> BigNum& operator %= (const T& b) { *this = *this % b; return *this; }
    template<typename T> BigNum& operator += (const T& b) { *this = *this + b; return *this; }
    template<typename T> BigNum& operator -= (const T& b) { *this = *this - b; return *this; }
    template<typename T> BigNum& operator *= (const T& b) { *this = *this * b; return *this; }
    template<typename T> BigNum& operator ^= (const T& b) { *this = *this ^ b; return *this; }
 
    BigNum operator ++ (int) { BigNum t = *this; *this += 1; return t; }
    BigNum operator -- (int) { BigNum t = *this; *this -= 1; return t; }
    BigNum& operator -- () { *this -= 1; return *this; }
    BigNum& operator ++ () { *this += 1; return *this; }
 
    template<typename T> BigNum& operator <<= (const T& b) { *this = *this << b; return *this; }
    template<typename T> BigNum& operator >>= (const T& b) { *this = *this >> b; return *this; }
 
    template<typename T> BigNum friend operator + (const T& a, const BigNum& b) { BigNum t = a; t = t + a; return t; }
    template<typename T> BigNum friend operator - (const T& a, const BigNum& b) { BigNum t = a; t = t - b; return t; }
    template<typename T> BigNum friend operator * (const T& a, const BigNum& b) { BigNum t = a; t = t * b; return t; }
    template<typename T> friend bool operator < (const T& a, const BigNum& b) { return b > a; }
    template<typename T> friend bool operator > (const T& a, const BigNum& b) { return b < a; }
    template<typename T> friend bool operator <= (const T& a, const BigNum& b) { return b >= a; }
    template<typename T> friend bool operator >= (const T& a, const BigNum& b) { return b <= a; }
    template<typename T> friend bool operator == (const T& a, const BigNum& b) { return b == a; }
    template<typename T> friend bool operator != (const T& a, const BigNum& b) { return b != a; }
 
    void print();       //输出大数
    int Size();            //返回大数长度
    int the_first();    //返回第一个数字
    int the_last();        //返回最后一位数字
    int to_int();       //转化为整数
    long long int to_long();
    string to_String();        //转化为string类型
    //char* to_char();
};
 
BigNum::BigNum(const int b)     //将一个int类型的变量转化为大数
{
    int c, d = b;
    len = 0;
    memset(a, 0, sizeof(a));
    while (d > MAXN) {
        c = d - (d / (MAXN + 1)) * (MAXN + 1);
        d = d / (MAXN + 1);
        a[len++] = c;
    }
    a[len++] = d;
}
BigNum::BigNum(const long long int b)
{
    long long int c, d = b;
    len = 0;
    memset(a, 0, sizeof(a));
    while (d > MAXN) {
        c = d - (d / (MAXN + 1)) * (MAXN + 1);
        d = d / (MAXN + 1);
        a[len++] = c;
    }
    a[len++] = d;
}
BigNum::BigNum(const string& s)
{
    int t, k, index, l, i;
    memset(a, 0, sizeof(a));
    l = s.size();
    len = l / DLEN;
    if (l % DLEN)
        len++;
    index = 0;
    for (i = l - 1; i >= 0; i -= DLEN) {
        t = 0;
        k = i - DLEN + 1;
        if (k < 0) k = 0;
        for (int j = k; j <= i; j++)
            t = t * 10 + s[j] - '0';
        a[index++] = t;
    }
}
BigNum::BigNum(const char* s)     //将一个字符串类型的变量转化为大数
{
    int t, k, index, l, i;
    memset(a, 0, sizeof(a));
    l = strlen(s);
    len = l / DLEN;
    if (l % DLEN)
        len++;
    index = 0;
    for (i = l - 1; i >= 0; i -= DLEN) {
        t = 0;
        k = i - DLEN + 1;
        if (k < 0) k = 0;
        for (int j = k; j <= i; j++)
            t = t * 10 + s[j] - '0';
        a[index++] = t;
    }
}
BigNum::BigNum(const BigNum& b) : len(b.len)  //拷贝构造函数
{
    memset(a, 0, sizeof(a));
    for (int i = 0; i < len; i++)
        a[i] = b.a[i];
}
BigNum& BigNum::operator = (const BigNum& n)   //重载赋值运算符,大数之间进行赋值运算
{
    len = n.len;
    memset(a, 0, sizeof(a));
    for (int i = 0; i < len; i++)
        a[i] = n.a[i];
    return *this;
}
BigNum& BigNum::operator = (const int& num)
{
    BigNum t(num);
    *this = t;
    return *this;
}
BigNum& BigNum::operator = (const long long int& num)
{
    BigNum t(num);
    *this = t;
    return *this;
}
void XD()
{
    cout << "A hidden egg! Good luck for u!" << endl;
}
 
template<typename T> BigNum BigNum::operator << (const T& b) const
{
    T temp = 1;
    for (int i = 0; i < b; i++)
        temp *= 2;
    BigNum t = (*this) * temp;
    return t;
}
template<typename T> BigNum BigNum::operator >> (const T& b) const
{
    T temp = 1;
    for (int i = 0; i < b; i++)
        temp *= 2;
    BigNum t = (*this) / temp;
    return t;
}
 
BigNum BigNum::operator + (const BigNum& b) const   //两个大数之间的相加运算
{
    BigNum t(*this);
    int i, big;
    big = b.len > len ? b.len : len;
    for (i = 0; i < big; i++) {
        t.a[i] += b.a[i];
        if (t.a[i] > MAXN) {
            t.a[i + 1]++;
            t.a[i] -= MAXN + 1;
        }
    }
    if (t.a[big] != 0)
        t.len = big + 1;
    else
        t.len = big;
    return t;
}
BigNum BigNum::operator - (const BigNum& b) const   //两个大数之间的相减运算
{
    int i, j, big;
    bool flag;
    BigNum t1, t2;
    if (*this > b) {
        t1 = *this;
        t2 = b;
        flag = 0;
    }
    else {
        t1 = b;
        t2 = *this;
        flag = 1;
    }
    big = t1.len;
    for (i = 0; i < big; i++) {
        if (t1.a[i] < t2.a[i]) {
            j = i + 1;
            while (t1.a[j] == 0)
                j++;
            t1.a[j--]--;
            while (j > i)
                t1.a[j--] += MAXN;
            t1.a[i] += MAXN + 1 - t2.a[i];
        }
        else
            t1.a[i] -= t2.a[i];
    }
    t1.len = big;
    while (t1.a[t1.len - 1] == 0 && t1.len > 1) {
        t1.len--;
        big--;
    }
    if (flag)
        t1.a[big - 1] = 0 - t1.a[big - 1];
    return t1;
}
 
BigNum BigNum::operator * (const BigNum& b) const   //两个大数之间的相乘运算
{
    BigNum ret;
    int i, j, up;
    int temp, temp1;
    for (i = 0; i < len; i++) {
        up = 0;
        for (j = 0; j < b.len; j++) {
            temp = a[i] * b.a[j] + ret.a[i + j] + up;
            if (temp > MAXN) {
                temp1 = temp - temp / (MAXN + 1) * (MAXN + 1);
                up = temp / (MAXN + 1);
                ret.a[i + j] = temp1;
            }
            else {
                up = 0;
                ret.a[i + j] = temp;
            }
        }
        if (up != 0) ret.a[i + j] = up;
    }
    ret.len = i + j;
    while (ret.a[ret.len - 1] == 0 && ret.len > 1)
        ret.len--;
    return ret;
}
template<typename T> BigNum BigNum::operator / (const T& b) const
{
    BigNum ret;
    T i, down = 0;
    for (i = len - 1; i >= 0; i--) {
        ret.a[i] = (a[i] + down * (MAXN + 1)) / b;
        down = a[i] + down * (MAXN + 1) - ret.a[i] * b;
    }
    ret.len = len;
    while (ret.a[ret.len - 1] == 0 && ret.len > 1)
        ret.len--;
    return ret;
}
template<typename T> T BigNum::operator % (const T& b) const
{
    T i, d = 0;
    for (i = len - 1; i >= 0; i--) {
        d = ((d * (MAXN + 1)) % b + a[i]) % b;
    }
    return d;
}
 
 
template<typename T> BigNum BigNum::operator^(const T& n) const    //大数的n次方运算
{
    BigNum t, ret(1);
    int i;
    if (n < 0) return 0;
    if (n == 0)
        return 1;
    if (n == 1)
        return *this;
    int m = n;
    while (m > 1) {
        t = *this;
        for (i = 1; (i << 1) <= m; i <<= 1)
            t = t * t;
        m -= i;
        ret = ret * t;
        if (m == 1) ret = ret * (*this);
    }
    return ret;
}
 
bool BigNum::operator > (const BigNum& b) const   //大数和另一个大数的大小比较
{
    int tot;
    if (len > b.len)
        return true;
    else if (len == b.len) {
        tot = len - 1;
        while (a[tot] == b.a[tot] && tot >= 0)
            tot--;
        if (tot >= 0 && a[tot] > b.a[tot])
            return true;
        else
            return false;
    }
    else
        return false;
}
 
bool BigNum::operator < (const BigNum& b) const
{
    int tot;
    if (len > b.len)
        return false;
    else if (len == b.len) {
        tot = len - 1;
        while (a[tot] == b.a[tot] && tot >= 0)
            tot--;
        if (tot >= 0 && a[tot] > b.a[tot])
            return false;
        else
            return false;
    }
    else
        return true;
}
 
bool BigNum::operator == (const BigNum& b) const
{
    int tot = len - 1;
    if (len != b.len)
        return false;
    while (a[tot] == b.a[tot] && tot >= 0)
        tot--;
    if (tot < 0)
        return true;
    return false;
}
int n;
void BigNum::print()    //输出大数
{
    int i;
    if (len >= n) {
        cout << a[len - 1];
        for (i = len - 2; i >= len - n; i--) {
            cout.width(DLEN);
            cout.fill('0');
            cout << a[i];
        }
        cout << endl;
    }
    else {
        cout << a[len - 1];
        for (i = len - 2; i >= 0; i--) {
            cout.width(DLEN);
            cout.fill('0');
            cout << a[i];
        }
        cout << endl;
    }
}
int BigNum::Size()
{
    int t = a[len - 1], cnt = 0;
    while (t) { t /= 10; cnt++; }
    cnt += (len - 1) * 4;
    return cnt;
}
int BigNum::the_first()
{
    int t = a[len - 1];
    while (t > 10) { t /= 10; }
    return t;
}
int BigNum::the_last()
{
    int t = a[0];
    return t % 10;
}
int BigNum::to_int()
{
    int i, num;
    num = a[len - 1];
    for (i = len - 2; i >= 0; i--)
        num = num * (MAXN + 1) + a[i];
    return num;
}
long long int BigNum::to_long()
{
    int i;
    long long int num;
    num = a[len - 1];
    for (i = len - 2; i >= 0; i--)
        num = num * (MAXN + 1) + a[i];
    return num;
}
string BigNum::to_String()
{
    int i;
    string s = "", tp = "";
    s += to_string(a[len - 1]);
    for (i = len - 2; i >= 0; i--) {
        tp = to_string(a[i]);
        int tot = tp.size();
        tp.insert(tp.begin(), 4 - tot, '0');
        s = s + tp;
    }
    return s;
}
 
int p[maxn];
int to[maxn];
int vis[maxn];
int ans;
BigNum lin, mod;
int gcd1(int x, int y) {
    return y ? gcd1(y, x % y) : x;
}
int gcd(BigNum x, int y) {
    return gcd1(y, x % y);
}
int main() {
    lin = BigNum(0);
    cin >> n;
    mod = BigNum(10) ^ n;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &p[i]);
        to[p[i]] = i;
    }
    BigNum ans = BigNum(1);
    for (int i = 1; i <= n; i++) {
        if (vis[i]) continue;
        int tmp = i;
        int res = 0;
        while (to[tmp] != i) {
            vis[tmp] = 1;
            tmp = to[tmp];
            res++;
        }
        res++;
        ans = ans / gcd(ans, res) * res;
    }
    ans.print();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/littlegoldgold/article/details/107600691