Submission #947198


Source Code Expand

#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <cstring>
#include <queue>
#include <ctime>
#include <cassert>
#include <cstdio>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
#include <bitset>

using namespace std;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define epr(...) fprintf(stderr, __VA_ARGS__)
#define db(x) cerr << #x << " = " << x << endl
#define db2(x, y) cerr << "(" << #x << ", " << #y << ") = (" << x << ", " << y << ")\n"; 
#define db3(x, y, z) cerr << "(" << #x << ", " << #y << ", " << #z << ") = (" << x << ", " << y << ", " << z << ")\n"
#define all(a) (a).begin(), (a).end()
#define sz(a) (int)(a).size()

#define equal equalll
#define less lesss
typedef long long ll;
const int N = 5e5 + 10;
const long long INF = 1e9 + 19;
const int MOD = 1e9 + 7;

int n;
int a[N];
ll fact[N];
bool use[N];
int tree[N];

void read() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
        a[i]--;
    }
}

int get(int r) {
    int sum = 0;
    for (; r > 0; r &= (r - 1))
        sum += tree[r];
    return sum;
}

void add(int pos, int val) {
    for (; pos <= n; pos |= (pos + 1))
        tree[pos + 1] += val;
}

ll solve() {
    fact[0] = 1;
    for (int i = 0; i <= n; i++)
        tree[i] = 0;
    for (int i = 1; i <= n; i++)
        fact[i] = (fact[i - 1] * i) % MOD;
    for (int i = 0; i < n; i++)
        use[i] = 0;

    for (int i = 0; i < n; i++)
        if (a[i] != -1)
            use[a[i]] = 1;
    vector<int> b;
    for (int i = 0; i < n; i++)
        if (!use[i])
            b.pb(i);

    ll answer = 0;  

    ll cntEmpty = 0;
    ll m = b.size();
    ll superCnt = 0;
    for (int i = n - 1; i >= 0; i--) {
        ll w = fact[n - i - 1];
        if (a[i] >= 0) {
            ll cnt = get(a[i]);
            answer = (answer + w * cnt % MOD * fact[b.size()]) % MOD;
            add(a[i], 1);

            ll t = lower_bound(all(b), a[i]) - b.begin();
            if (cntEmpty > 0)
                answer = (answer + t * 1ll * cntEmpty % MOD * fact[(int)b.size() - 1] % MOD * w) % MOD;
            superCnt = (superCnt + (m - t)) % MOD;
        }
        else {
            if (cntEmpty > 0) {
                ll par = (m * 1ll * (m - 1) / 2) % MOD;
                answer = (answer + fact[m - 2] * cntEmpty % MOD * par % MOD * w) % MOD;
            }
            answer = (answer + w * superCnt % MOD * fact[m - 1]) % MOD;
            cntEmpty++;
        }
    }

    answer = (answer + fact[b.size()]) % MOD;

    return answer;

}

ll stupid() {
    vector<int> perm;
    for (int i = 0; i < n; i++)
        perm.pb(i);
    int fact = 1;
    for (int i = 1; i <= n; i++)
        fact = (fact * i) % MOD;
    ll answer = 0;
    for (int i = 1; i <= fact; i++) {
        //if (i % 10000 == 0)
            //db(i);
        bool good = 1;
        for (int j = 0; j < n; j++)
            if (a[j] != -1)
                good &= perm[j] == a[j];
        
        if (good)
            answer = (answer + i) % MOD;
        next_permutation(all(perm));
    }
    return answer;

}

void genTest() {
    n = 5;
    for (int i = 0; i < n; i++)
        a[i] = i;
    random_shuffle(a, a + n);
    for (int i = 0; i < n; i++)
        if (rand() % 2 == 0)
            a[i] = -1;
}

void stress() {
    for (int tt = 0; ; tt++) {
        db(tt);
        genTest();
        auto r1 = solve();
        auto r2 = stupid();
        db2(r1, r2);
        if (r1 != r2) {
            cout << n << endl;
            for (int i = 0; i < n; i++)
                cout << a[i] + 1 << " ";
            cout << endl;
        }
        assert(r1 == r2);
    }

}


int main(){
#ifdef MY_DEBUG
    freopen("in", "r", stdin);
    //freopen("out", "w", stdout);
#endif
    if (1) {
        int k = 1;
        for (int tt = 0; tt < k; tt++) {
            read();
            cout << solve() << endl;
            //cout << stupid() << endl;
        }
    }
    else {
        stress();
    }

    return 0;
}






Submission Info

Submission Time
Task E - Encyclopedia of Permutations
User Belonogov
Language C++14 (GCC 5.4.1)
Score 1200
Code Size 4265 Byte
Status AC
Exec Time 128 ms
Memory 10740 KB

Compile Error

./Main.cpp: In function ‘void read()’:
./Main.cpp:44:20: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &n);
                    ^
./Main.cpp:46:27: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d", &a[i]);
                           ^

Judge Result

Set Name Sample Subtask All
Score / Max Score 0 / 0 500 / 500 700 / 700
Status
AC × 5
AC × 33
AC × 58
Set Name Test Cases
Sample 0_000.txt, 0_001.txt, 0_002.txt, 0_003.txt, 0_004.txt
Subtask 0_000.txt, 0_001.txt, 0_002.txt, 0_003.txt, 0_004.txt, 1_005.txt, 1_006.txt, 1_007.txt, 1_008.txt, 1_009.txt, 1_010.txt, 1_011.txt, 1_012.txt, 1_013.txt, 1_014.txt, 1_015.txt, 1_016.txt, 1_017.txt, 1_018.txt, 1_019.txt, 1_020.txt, 1_021.txt, 1_022.txt, 1_023.txt, 1_024.txt, 1_025.txt, 1_026.txt, 1_027.txt, 1_028.txt, 1_029.txt, 1_030.txt, 1_031.txt, 1_032.txt
All 0_000.txt, 0_001.txt, 0_002.txt, 0_003.txt, 0_004.txt, 1_005.txt, 1_006.txt, 1_007.txt, 1_008.txt, 1_009.txt, 1_010.txt, 1_011.txt, 1_012.txt, 1_013.txt, 1_014.txt, 1_015.txt, 1_016.txt, 1_017.txt, 1_018.txt, 1_019.txt, 1_020.txt, 1_021.txt, 1_022.txt, 1_023.txt, 1_024.txt, 1_025.txt, 1_026.txt, 1_027.txt, 1_028.txt, 1_029.txt, 1_030.txt, 1_031.txt, 1_032.txt, 2_033.txt, 2_034.txt, 2_035.txt, 2_036.txt, 2_037.txt, 2_038.txt, 2_039.txt, 2_040.txt, 2_041.txt, 2_042.txt, 2_043.txt, 2_044.txt, 2_045.txt, 2_046.txt, 2_047.txt, 2_048.txt, 2_049.txt, 2_050.txt, 2_051.txt, 2_052.txt, 2_053.txt, 2_054.txt, 2_055.txt, 2_056.txt, 2_057.txt
Case Name Status Exec Time Memory
0_000.txt AC 3 ms 256 KB
0_001.txt AC 3 ms 256 KB
0_002.txt AC 3 ms 256 KB
0_003.txt AC 3 ms 256 KB
0_004.txt AC 3 ms 256 KB
1_005.txt AC 3 ms 256 KB
1_006.txt AC 3 ms 256 KB
1_007.txt AC 3 ms 256 KB
1_008.txt AC 3 ms 384 KB
1_009.txt AC 3 ms 256 KB
1_010.txt AC 3 ms 384 KB
1_011.txt AC 3 ms 384 KB
1_012.txt AC 3 ms 384 KB
1_013.txt AC 3 ms 256 KB
1_014.txt AC 3 ms 384 KB
1_015.txt AC 3 ms 256 KB
1_016.txt AC 3 ms 384 KB
1_017.txt AC 3 ms 256 KB
1_018.txt AC 3 ms 384 KB
1_019.txt AC 3 ms 256 KB
1_020.txt AC 3 ms 256 KB
1_021.txt AC 3 ms 256 KB
1_022.txt AC 3 ms 256 KB
1_023.txt AC 3 ms 256 KB
1_024.txt AC 3 ms 256 KB
1_025.txt AC 3 ms 256 KB
1_026.txt AC 3 ms 256 KB
1_027.txt AC 3 ms 256 KB
1_028.txt AC 3 ms 384 KB
1_029.txt AC 3 ms 256 KB
1_030.txt AC 3 ms 256 KB
1_031.txt AC 3 ms 256 KB
1_032.txt AC 3 ms 384 KB
2_033.txt AC 58 ms 10740 KB
2_034.txt AC 30 ms 5496 KB
2_035.txt AC 72 ms 10740 KB
2_036.txt AC 66 ms 10100 KB
2_037.txt AC 85 ms 10740 KB
2_038.txt AC 75 ms 9716 KB
2_039.txt AC 98 ms 10740 KB
2_040.txt AC 48 ms 5496 KB
2_041.txt AC 110 ms 10740 KB
2_042.txt AC 21 ms 2176 KB
2_043.txt AC 117 ms 9720 KB
2_044.txt AC 76 ms 6904 KB
2_045.txt AC 123 ms 9720 KB
2_046.txt AC 118 ms 9336 KB
2_047.txt AC 127 ms 9212 KB
2_048.txt AC 54 ms 4352 KB
2_049.txt AC 128 ms 8960 KB
2_050.txt AC 83 ms 6144 KB
2_051.txt AC 87 ms 8576 KB
2_052.txt AC 79 ms 7808 KB
2_053.txt AC 58 ms 10740 KB
2_054.txt AC 90 ms 8576 KB
2_055.txt AC 76 ms 8576 KB
2_056.txt AC 76 ms 8576 KB
2_057.txt AC 82 ms 9720 KB