Hi everyone.
Please help me to solve this problem.
You are given a binary string s which is permutation of 0000000000000001111111111111111 (15 0s and 16 1s), you should find x such that s is lexiographic xth permutation of 0000000000000001111111111111111.
Very easy problem since 1798 in CHINA
We can compute the total number of permutation for x zeros and y ones by (x+y)! / (x! * y!). Let f(x,y) be (x+y)! / (x! * y!).
c0=15,c1=16 ans=0
Iterate on index i from 0 , If s[i] is '1' then there will be some number of permutation which are smaller than the current permutation , at this index, so we have to add the number of such permutations. for s[i] = '0' then we don't have any element smaller than 0 so the permutation can't be smaller at this index.
If s[i] == '1' then the permutation to be smaller at this index we need to place zero at this index, if c0==0 then just continue else when we place zero then any permutation of the remaining elements will be smaller so add f(c0-1,c1) to ans.
subtract one from c0 or c1 according to s[i], if s[i]=='0' then from c0 else from c1.
Thank you.
I have an another question when we are given x how to find s.
I think that can be solve in a similar way.
At each index we can try to put '1' if the permutation smaller than current exceeds x we are forced to put 0 else we put 1,at the end we will the desired permutation.
Can you please give code for both.
Thank you, but get_perm is working wrong (always returns 31 1s).
UPD: worked, it was overflow.
yeah you are right we might have to use int128(__int128 in G++ 20) or use some other way around.
$$$31*30*....*17 \ge 10^{20}$$$
To avoid overflows it's better to divide simultaneously.
Why does this work? We first compute $$$C(p, 1)$$$, which in the next iteration will become $$$C(p, 2)$$$, and so on. Thus, dividing will not be a problem.
Thanks for suggesting the change, but you forgot to use long long.
Nice catch. It could possibly overflow during multiplication.
Solution: