传送门:点击打开链接
题意:求两个排列的次序相加取模n!后,得到新的次序,然后输出这个次序对应的排列
思路:康托展开+逆展开+高精度。康托展开其实是个求逆序对的过程,逆展开实际上是一个找第k大的过程,都可以使用线段树来完成
因为数字非常大,所以肯定是要用高精度的,但是这里的高精度很特别,不是使用十进制的高精度,而是使用阶乘进制的高精度,这样就可以和康托展开和逆展开完美的结合起来了。
#include<map> #include<set> #include<cmath> #include<ctime> #include<stack> #include<queue> #include<cstdio> #include<cctype> #include<string> #include<vector> #include<cstring> #include<iomanip> #include<iostream> #include<algorithm> #include<functional> #define fuck(x) cout<<"["<<x<<"]" #define FIN freopen("input.txt","r",stdin) #define FOUT freopen("output.txt","w+",stdout) using namespace std; typedef long long LL; typedef pair<int, int>PII; const int MX = 2e5 + 5; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int S[MX << 2], A[MX], B[MX], n; void push_up(int rt) { S[rt] = S[rt << 1] + S[rt << 1 | 1]; } void add(int x, int l, int r, int rt) { if(l == r) { S[rt]++; return; } int m = (l + r) >> 1; if(x <= m) add(x, lson); else add(x, rson); push_up(rt); } int sum(int L, int R, int l, int r, int rt) { if(L <= l && r <= R) return S[rt]; int m = (l + r) >> 1, ret = 0; if(L <= m) ret += sum(L, R, lson); if(R > m) ret += sum(L, R, rson); return ret; } void build(int l, int r, int rt) { if(l == r) { S[rt] = 1; return; } int m = (l + r) >> 1; build(lson); build(rson); push_up(rt); } int query(int x, int l, int r, int rt) { if(l == r) { S[rt]--; return l; } int m = (l + r) >> 1, ret; if(x <= S[rt << 1]) ret = query(x, lson); else ret = query(x - S[rt << 1], rson); push_up(rt); return ret; } void Contor(int A[]) { memset(S, 0, sizeof(S)); for(int i = 0; i < n; i++) { int t; scanf("%d", &t); t++; A[n - i - 1] = t - sum(1, t, 1, n, 1) - 1; add(t, 1, n, 1); } } void solve() { build(1, n, 1); A[0] = 0; for(int i = n - 1; i >= 0; i--) { int x = query(A[i] + 1, 1, n, 1) - 1; printf("%d%c", x, i == 0 ? '\n' : ' '); } } int main() { //FIN; while(~scanf("%d", &n)) { Contor(A); Contor(B); for(int i = 1, t = 0; i < n; i++) { A[i] += B[i] + t; t = A[i] / (i + 1); A[i] -= t * (i + 1); } solve(); } return 0; }