Challenge: Value of all Permutations
Subdomeniu: Combinatorics (combinatorics)
Scor cont: 80.0 / 80
Submission status: Accepted
Submission score: 1.0
Submission ID: 464762597
Limbaj: cpp14
Link challenge: https://www.hackerrank.com/challenges/value-of-all-permutations/problem
Cerinta
You are given an array $A$ of size $N$. You are asked to answer $Q$ queries.
Each query contains a number $M$.
For each *distinct* permutation of the array $A$, you need to print the sum of the values returned by the `find` function.
As the sum can be too large, output it modulo $P$, which is a prime and given in input.
find(int permutation_A[], int M)
{
x = Length(permutation_A)
sum = 0
for(i = 0; i < x; i++) {
if (permutation_A[i] <= M)
sum = sum + permutation_A[i]
else
break
}
return sum
}
**Input Format**
The first line of input contains $P$.
The second line of input contains $N$. The next line contains $N$ numbers $A[0] \ldots A[N-1]$ separated by single spaces.
The next line contains $Q$, the number of queries to follow. Each subsequent line contains one positive integer $M$.
**Output Format**
For each query, output as asked above.
**Constraints**
$1000000 \le P \le 2000003$
$1 \le N \le 10^5$
$1 \le Q \le 10^5$
$1 \le A[i], M \le 10^9$
**Sample Input**
2000003
5
4 2 3 1 4
2
1
2
**Sample Output**
12
45
**Explanation**
*Query 1*:
Consider all permutations. if the first number is greater than 1, then the loop will break in the beginning itself. There are a total of 60 distinct permutations out of which 48 will give 0. The remaining 12 will fetch 1 each from the function. Thus the answer is 12.
Cod sursa
#include <bits/stdc++.h>
using namespace std;
long long modpow(long long a, long long e, long long mod) {
long long r = 1 % mod;
a %= mod;
if (a < 0) a += mod;
while (e > 0) {
if (e & 1LL) r = (__int128)r * a % mod;
a = (__int128)a * a % mod;
e >>= 1LL;
}
return r;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long P;
cin >> P;
int N;
cin >> N;
vector<long long> A(N);
for (int i = 0; i < N; ++i) cin >> A[i];
vector<long long> fact(N + 1, 1 % P);
for (int i = 1; i <= N; ++i) fact[i] = (__int128)fact[i - 1] * i % P;
unordered_map<long long, int> cnt;
cnt.reserve(N * 2 + 1);
for (auto x : A) cnt[x]++;
long long total_perm = fact[N];
for (auto &kv : cnt) {
total_perm = (__int128)total_perm * modpow(fact[kv.second], P - 2, P) % P;
}
sort(A.begin(), A.end());
vector<long long> pref(N + 1, 0);
for (int i = 0; i < N; ++i) {
long long v = A[i] % P;
if (v < 0) v += P;
pref[i + 1] = pref[i] + v;
if (pref[i + 1] >= P) pref[i + 1] -= P;
}
int Q;
cin >> Q;
while (Q--) {
long long M;
cin >> M;
int s = upper_bound(A.begin(), A.end(), M) - A.begin();
if (s == 0) {
cout << 0 << '\n';
continue;
}
long long W = pref[s];
long long den = N - s + 1; // always >=1
long long ans = total_perm;
ans = (__int128)ans * W % P;
ans = (__int128)ans * modpow(den, P - 2, P) % P;
cout << ans << '\n';
}
return 0;
}
HackerRank Combinatorics – Value of all Permutations
