1 条题解

  • 0
    @ 2023-4-27 19:37:45
    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    const int MOD = 998244353;
    const int MAXN = 1000000;
    int n;
    int a[MAXN + 5];
    // 纯暴力按字典序枚举排列,看第几个是输入的(5分)
    namespace subtask1
    {
        vector<int> now;
        bool check()
        {
            for (int i = 1; i <= n; i++)
                if (a[i] != now[i - 1])
                    return false;
            return true;
        }
        void work()
        {
            for (int i = 1; i <= n; i++)
                now.push_back(i);
            int cnt = 1;
            do
            {
                if (check())
                {
                    cout << cnt << "\n";
                    return;
                }
                cnt++;
            } while (next_permutation(now.begin(), now.end()));
        }
    }
    // 暴力康托展开(20分)
    namespace subtask2
    {
        int fact[MAXN + 5]; // i!
        bool vis[MAXN + 5]; // i是否还在
        // 判断1~x-1还存在几个数
        int cnt(int x)
        {
            int res = 0;
            for (int i = 1; i <= x - 1; i++)
                res += vis[i];
            return res;
        }
        void work()
        {
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i % MOD,
                vis[i] = true;
            int res = 1;
            for (int i = 1; i <= n; i++)
            {
                res = (res + cnt(a[i]) * fact[n - i] % MOD) % MOD;
                //cout << a[i] << "~" << cnt(a[i]) << "~" << fact[n - i] << endl;
                vis[a[i]] = false;
            }
            cout << res << "\n";
        }
    }
    //树状数组优化康托展开
    namespace subtask3
    {
        int fact[MAXN + 5]; // i!
        int t[MAXN + 5];
        int lowbit(int x)
        {
            return x & (-x);
        }
        void add(int pos, int x)
        {
            for (int i = pos; i <= n; i += lowbit(i))
                t[i] += x;
        }
        int query(int pos)
        {
    
            int res = 0;
            for (int i = pos; i >= 1; i -= lowbit(i))
                res += t[i];
            return res;
        }
        void work()
        {
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i % MOD,
                add(i, 1);
            int res = 1;
            for (int i = 1; i <= n; i++)
            {
                res = (res + query(a[i] - 1) * fact[n - i] % MOD) % MOD;
                add(a[i], -1);
            }
            cout << res << "\n";
        }
    }
    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        if (n <= 10)
            subtask1::work();
        else if (n <= 5000)
            subtask2::work();
        else
            subtask3::work();
        return 0;
    }
    
    • 1

    信息

    ID
    1273
    时间
    1000ms
    内存
    64MiB
    难度
    6
    标签
    递交数
    37
    已通过
    12
    上传者