Test instructions
N (2*10^5) elements are arranged in n! species with Perm (x) to denote the sequence of the dictionary sequence x (starting from 0) using Ord (permutation y) to denote the dictionary of Y in order of the input arrangement p and Q for Perm ([Ord (P) +ord (q)]%n!)
Ideas:
It is easy to think about the p[i] if it is a small number of D, then it means that the whole permutation of the d-1 numbers that are smaller than it has been counted.
Example 35142 the 4th bit is 4 It is the 2nd small (1 and 3 have appeared) so 35124 this situation must have been counted
So we can find out for P and Q, respectively, that the sequence is the first and the same as Ord (P) and Ord (q), then we can make perm according to the inverse process of the process.
Now the difficulty is n! this number is too big to calculate
But we find that the things we are interested in are factorial!! So we just need to record (N-1)! (n-2)! ...... After the number of occurrences of Ord (p) and Ord (q), this array of numbers is scanned like a simulated high precision to make [Ord (p) +ord (q)]%n! results.
I'm doing "query number small" This feature uses two points + tree array so the complexity is O (nlog^2n)
Code:
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include < algorithm> #include <map> #include <set> #include <vector> #include <queue> #include < cstdlib> #include <ctime> #include <cmath>using namespace std;typedef long long LL; #define N 200010#define Lowbit (x) (x& (×)) int n;int a[n], B[n];int f[n], c[n];inline void scand (int &ret) {char C; ret = 0; while ((c = GetChar ()) < ' 0 ' | | c > ' 9 '); while (c >= ' 0 ' && C <= ' 9 ') ret = ret * + (C-' 0 '), C = GetChar ();} void Add (int x, int y) {while (x <= N) {c[x] + = y; x + = Lowbit (x); }}int sum (int x) {int res = 0; while (x) {res + = c[x]; X-= Lowbit (x); } return res; void Init () {memset (c, 0, sizeof (c)); for (int i = 1; I <= n; i++) Add (i, 1);} int main () {Scand (n); for (int i = 1; I <= n; i++) {Scand (a[i]); a[i]++; } for (int i = 1; I <= n; i++) {Scand (b[i]); b[i]++; } init (); for (int i = 1; i < n; i++) {int les = SUM (a[i]-1); F[n-i] + = les; Add (A[i],-1); } init (); for (int i = 1; i < n; i++) {int les = SUM (b[i]-1); F[n-i] + = les; Add (B[i],-1); } for (int i = 1; i < n; i++) {f[i + 1] + = F[i]/(i + 1); F[i] = f[i]% (i + 1); }//printf ("f:\n"); for (int i = 1; I <= n; i++) printf ("%d", f[i]); printf ("\ n"); Init (); int SML = 1; for (int i = n-1; I >= 1; i--) {int L = 1, R = N, Mid, tmp, ans =-1; while (L <= r) {mid = (L + r)/2; TMP = SUM (mid-1); if (tmp <= F[i]) {L = mid + 1; Ans = mid; } else {//ans = mid; R = mid-1; }} if (ans = =-1) {ans = SML; } printf("%d", ans-1); Add (ans,-1); while (!C[SML]) sml++; printf ("c:\n"); for (int i = 1; I <= n; i++) printf ("%d", c[i]); printf ("\ n"); printf ("Sml%d\n", SML); } for (int i = 1; I <= n; i++) {if (C[i]) {printf ("%d\n", i-1); Break }} return 0;}
Codeforces 501D Misha and permutations summation