[Codeforces 501D] - Misha and Permutations Summation
题意是给你两个长度为$n$的排列,他们分别是$n$的第$a$个和第$b$个全排列。输出$n$的第$\left(a+b \right)\textrm{mod} \, n!$个全排列。
一种很容易的想法是直接把$a$和$b$求出来,然后计算$\left(a+b \right)\textrm{mod} \, n!$的值并直接求对应的排列,但是由于$n$的范围$\left(n\leq200000\right)$直接求值显然不可行。
因此,考虑全排列的康托展开(Cantor expansion) 任意一种排列在全排列中对应的序号为$$\sum_{i=1}^{n}{a}_{i}\times i!$$
于是,将输入的两个排列分别写成这种形式,然后遍历$n$相加,由于结果需要对$n!$取模,因此从最低位开始逐项将$a_i$加到$a_i+1$上去,最后将最高位的$a_n$模掉$n$即可。
之后,只要拟用康托展开即可求出对应的排列。
在实现过程中,由于需要维护"当前还没有使用过的第k大的数",因此可以用树状数组BIT维护。恢复排列时用树状数组+二分即可。
复杂度$\mathcal{O}({n\log}^{2}n )$
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define GETNUM(num) scanf("%d",&num)
#define IT_PT(BEG,END,TYPE,REG) copy(BEG,END,ostream_iterator<TYPE>(cout,REG))
#define CLR(ARR,NUM) memset(ARR,NUM,sizeof(ARR))
#define faster_io() ios_base::sync_with_stdio(false)
using namespace std;
const int MAXN = 200010;
int la[MAXN], lb[MAXN], a[MAXN], b[MAXN], f[MAXN], s[MAXN];
typedef int bit_type;
const int bit_maxn = MAXN;
int n;
int ff[MAXN];
bit_type tree[bit_maxn]; int lowbit(int x)
{
return x & (-x);
} void add(int x, int d)
{
x++;
while(x <= n) {
tree[x] += d;
x += lowbit(x);
}
} bit_type sum(int x)
{
x++;
bit_type ans = 0;
while(x) {
ans += tree[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
cin >> n;
for(int i = 0; i < n; i++)
GETNUM(la[i]);
for(int i = 0; i < n; i++)
GETNUM(lb[i]);
CLR(tree, 0);
for(int i = 0; i < n; i++) {
add(i, 1);
}
for(int i = 0; i < n; i++) {
a[i] = sum(la[i] - 1);
add(la[i], -1);
}
CLR(tree, 0);
for(int i = 0; i < n; i++) {
add(i, 1);
}
for(int i = 0; i < n; i++) {
b[i] = sum(lb[i] - 1);
add(lb[i], -1);
s[i] = a[i] + b[i];
} CLR(tree, 0);
for(int i = 0; i < n; i++) {
add(i, 1);
ff[i] = 1;
}
for(int i = n - 1; i > 0; i--) {
s[i - 1] += s[i] / (n - i);
s[i] %= (n - i);
}
s[0] %= n;
int rr = n - 1;
for(int i = 0; i < n; i++) {
int r = rr;
int l = 0;
while(l < r) {
int mid = l + (r - l + 1) / 2;
int t = sum(mid - 1);
if(t <= s[i]) l = mid;
else r = mid - 1;
}
add(l, -1);
ff[l] = 0;
if(!i) {
printf("%d", l);
} else {
printf(" %d", l);
}
while(!ff[rr]) {
rr--;
}
}
return 0;
}
[Codeforces 501D] - Misha and Permutations Summation的更多相关文章
- Misha and Permutations Summation
A - Misha and Permutations Summation 首先这个 mod n! 因为数量级上的差别最多只会对康拓展开的第一项起作用所以这个题并不需要把 ord (p) 和 ord ( ...
- 【codeforces 501D】Misha and Permutations Summation
[题目链接]:http://codeforces.com/problemset/problem/501/D [题意] 给你两个排列; 求出它们的字典序num1和num2; 然后让你求出第(num1+n ...
- Codeforces Round #285 (Div.1 B & Div.2 D) Misha and Permutations Summation --二分+树状数组
题意:给出两个排列,求出每个排列在全排列的排行,相加,模上n!(全排列个数)得出一个数k,求出排行为k的排列. 解法:首先要得出定位方法,即知道某个排列是第几个排列.比如 (0, 1, 2), (0, ...
- Codeforces Round #285 (Div. 1) B - Misha and Permutations Summation 康拓展开+平衡树
思路:很裸的康拓展开.. 我的平衡树居然跑的比树状数组+二分还慢.. #include<bits/stdc++.h> #define LL long long #define fi fir ...
- CF501D Misha and Permutations Summation(康托展开)
将一个排列映射到一个数的方法就叫做康托展开.它的具体做法是这样的,对于一个给定的排列{ai}(i=1,2,3...n),对于每个ai求有多少个aj,使得j>i且ai>aj,简单来说就是求a ...
- CodeForces 501B Misha and Changing Handles(STL map)
Misha hacked the Codeforces site. Then he decided to let all the users change their handles. A user ...
- codeforces 501C. Misha and Forest 解题报告
题目链接:http://codeforces.com/problemset/problem/501/C 题目意思:有 n 个点,编号为 0 - n-1.给出 n 个点的度数(即有多少个点跟它有边相连) ...
- Codeforces Round #337 Alphabet Permutations
E. Alphabet Permutations time limit per test: 1 second memory limit per test: 512 megabytes input: ...
- codeforces 341C Iahub and Permutations(组合数dp)
C. Iahub and Permutations time limit per test 1 second memory limit per test 256 megabytes input sta ...
随机推荐
- linux常用命令(4)rm命令
rm是一个危险的命令,使用的时候要特别当心,尤其对于新手,否则整个系统就会毁在这个命令(比如在/(根目录)下执行rm * -rf).所以,我们在执行rm之前最好先确认一下在哪个目录,到底要删除什么东西 ...
- c++ 顺序容器学习 - 容器适配器
摘要: 对 容器适配器 的疑问. 刚开始接触 容器适配器 时,总感觉怪怪的,认为多此一举,顺手搜了搜,原来我在这一点is not alone: STL容器适配器的用途 其中有个老兄说的好,这里 引用一 ...
- runAllManagedModulesForAllRequests 和 invalid url
有这样的经验, 在本地的 IIS 上网站运行正常,但是发布到服务器上就一堆怪怪的问题 : MVC routing not work http://stackoverflow.com/questions ...
- XML CDATA
/* <![CDATA[ */var mv_dynamic_to_top = {"text":"To Top","version":& ...
- codeforces Upgrading Array
思路:对于每个数分解质因子然后记录每一个质因子的个数,对与在b中出现的质因子就减去1,否则加1,求出总的,然后从后面一次对它们的最大公约数,然后判断除以最大公约数之后,改变量是不是变化,求最大值,变化 ...
- BZOJ1621: [Usaco2008 Open]Roads Around The Farm分岔路口
1621: [Usaco2008 Open]Roads Around The Farm分岔路口 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 521 S ...
- 数学(莫比乌斯函数):BZOJ 2440 完全平方数
Description 小 X 自幼就很喜欢数.但奇怪的是,他十分讨厌完全平方数.他觉得这些 数看起来很令人难受.由此,他也讨厌所有是完全平方数的正整数倍的数.然而 这丝毫不影响他对其他数的热爱. 这 ...
- 【模拟】Codeforces 705B Spider Man
题目链接: http://codeforces.com/problemset/problem/705/B 题目大意: 两个人玩游戏,总共N个数,分别求前I(I=1 2 3...n)个数时游戏的获胜者是 ...
- 【转】Ansys 13.0 flexlm not running完美解决方案
http://jingyan.baidu.com/article/af9f5a2dd9843a43150a4550.html 实测,12.1 用此方法问题同样得解.
- python关键字、转义符和字符串格式化
最近在学learn python the hard way,学习到第37章,进行了关于关键字.转义符和字符串格式化的总结.看手头上的中文版没有及时更新.于是就把这些翻译过来,以作查阅. 关键字: 关键 ...