如果在阅读本文之前对于康托展开没有了解的同学请戳一下这里:  简陋的博客    百度百科

题目描述

N(1<=N<=20)头牛,编号为1...N,正在与FJ玩一个疯狂的游戏。奶牛会排成一行(牛线),问FJ此时的行号是多少。之后,FJ会给牛一个行号,牛必须按照新行号排列成线。

行号是通过以字典序对行的所有排列进行编号来分配的。比如说:FJ有5头牛,让他们排为行号3,排列顺序为:

1:1 2 3 4 5

2:1 2 3 5 4

3:1 2 4 3 5

因此,牛将在牛线1 2 4 3 5中。

之后,奶牛排列为“1 2 5 3 4”,并向FJ问他们的行号。继续列表:

4:1 2 4 5 3

5:1 2 5 3 4

FJ可以看到这里的答案是5。

FJ和奶牛希望你的帮助玩他们的游戏。他们需要K(1<=K<=10000)组查询,查询有两个部分:C_i将是“P”或“Q”的命令。

如果C_i是'P',则查询的第二部分将是一个整数A_i(1 <= A_i <= N!),它是行号。此时,你需要回答正确的牛线。

如果C_i是“Q”,则查询的第二部分将是N个不同的整数B_ij(1 <= B_ij <= N)。这将表示一条牛线,此时你需要输出正确的行号。

输入格式:

* Line 1: Two space-separated integers: N and K

* Lines 2..2*K+1: Line 2*i and 2*i+1 will contain a single query.

Line 2*i will contain just one character: 'Q' if the cows are lining up and asking Farmer John for their line number or 'P' if Farmer John gives the cows a line number.

If the line 2*i is 'Q', then line 2*i+1 will contain N space-separated integers B_ij which represent the cow line. If the line 2*i is 'P', then line 2*i+1 will contain a single integer A_i which is the line number to solve for.

输出格式:

* Lines 1..K: Line i will contain the answer to query i.

If line 2*i of the input was 'Q', then this line will contain a single integer, which is the line number of the cow line in line 2*i+1.

If line 2*i of the input was 'P', then this line will contain N space separated integers giving the cow line of the number in line 2*i+1.

下面是正文:

这是一个康托展开的(模板)题

对于n个数的全排列,这个地方我们可以运用 STL 中的next_permunation进行优化

ai代表第i个元素在未出现的元素中是第几大 即在第i~n位的元素中的rank

对与 2 1 3
对于 2 只有1比它大 所以排第1大;
对于 1 没有比它大的 所以排第0大 ;
对于 3 没有和它比较的 所以排第0大;
a3=3,a2=0,a1=0

所以ans=3;

康托展开逆运算
已知某一全排列在所有排列中排第x
可以求得 这个全排列

例如 ans=20; 求它的全排列

第一次 20/(3!) =3……2 说明在第一个元素后面有3个比现在的元素小 这个元素就是4;
第二次 2/(2!) =1……0 说明在这个元素后面有一个比它小 这只能是2;
第三次 0/(1!) =0……0 说明这个元素后面没有比它小的 只能是 1;
第四次 0/(0!) =0……0 只剩3了;

简而言之就是通过不断地向下除来实现一个降低复杂度

那么我们就可以通过这个来得到他们的序列排序了,不过这里我们要注意的一点就是这是对于整个序列所进行的一个排序,以及排序之间的空格

下面上代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
long long n,m,fac[],vst[],a[],x;
char op;
void init() //初始化
{
for(int i=;i<=;i++) // 这里到了28就已经十分大了,所以无需再往后运算
fac[i]=;
}
ll contor(ll x[]) //Cantor的运算
{
long long ans=;
for(int i=;i<=n;i++)
{
int tag=; //标记为0
for(int j=i+;j<=n;j++)
{
if(x[i]>x[j])
tag++; //更新标记
}
ans+=tag*fac[n-i];
}
return ans+;
}
void recontor(ll x) //Cantor的逆运算
{
memset(vst,,sizeof(vst));
x--;
ll k;
for(int i=;i<=n;i++)
{
ll ans=x/fac[n-i]; //Cantor的实际操作1
for(int j=;j<=n;j++)
{
if(!vst[j])
{
if(!ans) //加入ans为0的话就赋值
{
k=j;
break; //时间上的优化
}
ans--;
}
}
printf("%d ",k);
vst[k]=; //回溯
x%=fac[n-i]; //Cantor的实际操作2
}
printf("\n");
}
int main()
{
scanf("%lld%lld",&n,&m);
init();
for(int i=;i<=n;i++)
fac[i]=i*fac[i-]; //康托展开的预处理
for(int i=;i<=m;i++)
{
cin>>op; //判断题目所给的标记
if(op=='P')
{
scanf("%lld",&x);
recontor(x); //康托展开逆运算,进行加进去
}
if(op=='Q')
{
for(int i=;i<=n;i++)
scanf("%lld",&a[i]); //康托展开运算,运算
printf("%lld\n",contor(a));
}
}
return ;
}

[洛谷P3014][USACO11FEB]牛线Cow Line (康托展开)(数论)的更多相关文章

  1. 洛谷 P3014 [USACO11FEB]牛线Cow Line

    P3014 [USACO11FEB]牛线Cow Line 题目背景 征求翻译.如果你能提供翻译或者题意简述,请直接发讨论,感谢你的贡献. 题目描述 The N (1 <= N <= 20) ...

  2. P3014 [USACO11FEB]牛线Cow Line && 康托展开

    康托展开 康托展开为全排列到一个自然数的映射, 空间压缩效率很高. 简单来说, 康托展开就是一个全排列在所有此序列全排列字典序中的第 \(k\) 大, 这个 \(k\) 即是次全排列的康托展开. 康托 ...

  3. 洛谷——P2952 [USACO09OPEN]牛线Cow Line

    P2952 [USACO09OPEN]牛线Cow Line 题目描述 Farmer John's N cows (conveniently numbered 1..N) are forming a l ...

  4. 洛谷P3045 [USACO12FEB]牛券Cow Coupons

    P3045 [USACO12FEB]牛券Cow Coupons 71通过 248提交 题目提供者洛谷OnlineJudge 标签USACO2012云端 难度提高+/省选- 时空限制1s / 128MB ...

  5. 洛谷 P3111 [USACO14DEC]牛慢跑Cow Jog_Sliver

    P3111 [USACO14DEC]牛慢跑Cow Jog_Sliver 题目描述 The cows are out exercising their hooves again! There are N ...

  6. 洛谷:P2952 [USACO09OPEN]牛线Cow Line:题解

    题目链接:https://www.luogu.org/problemnew/show/P2952 分析: 这道题非常适合练习deque双端队列,~~既然是是练习的板子题了,建议大家还是练练deque, ...

  7. 洛谷P2901 [USACO08MAR]牛慢跑Cow Jogging

    题目描述 Bessie has taken heed of the evils of sloth and has decided to get fit by jogging from the barn ...

  8. 洛谷 P2419 [USACO08JAN]牛大赛Cow Contest

    题目背景 [Usaco2008 Jan] 题目描述 N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a p ...

  9. 洛谷—— P2419 [USACO08JAN]牛大赛Cow Contest

    https://www.luogu.org/problem/show?pid=2419 题目背景 [Usaco2008 Jan] 题目描述 N (1 ≤ N ≤ 100) cows, convenie ...

随机推荐

  1. oracle存储过程,sql语句执行时间

    create or replace procedure sum_info is i integer; temp1 varchar2(50); temp2 varchar2(50); t1 date; ...

  2. C++获取当前所有进程的完整路径

    实现代码 #include <stdio.h> #include <windows.h> #include <tlhelp32.h> #include <st ...

  3. 【转】Linux中常见问题(磁盘 定时任务)

    [转]Linux中常见问题(磁盘 定时任务) 第1章 linux无法上网 1)     第一步,先ping域名. ping www.baidu.com 2)再ping一个公网ip , ping 223 ...

  4. 03-Bootstrap学习

    一.Bootstrap的介绍 凡是使用过Bootstrap的开发者,都不在乎做这么两件事情:复制and粘贴.哈哈~,是的使用Bootstrap非常简单,但是在复制粘贴之前,需要先对Bootstrap的 ...

  5. JS正则表达式大全(附例子)

    0 前言 正则表达式用来字符串匹配,格式校验,非常cool且有趣. 1 正则表达式中的特殊字符 \ 做为转义,即通常在"\"后面的字符不按原来意义解释,如/b/匹配字符" ...

  6. git命令行提交并且同步到远程代码库

    远程代码库以github为例 1.打开 git bash 2.进入项目目录 cd /e/myGitProjects/test 3.提交到本地git仓库 git add -Agit commit -m ...

  7. C#面向对象(封装)

    以上就是面向对象的封装和初始化:

  8. MariaDB和mySQL到底区别在哪,实验说明问题!

    先看图,插入数据和时间的对数图,实验条件一直且关闭了mysql默认事务保证不是单条事务而是批量事务 另外确保了mysql and mariaDB都是在支持事务存储引擎下测试的. MySQL之父Wide ...

  9. Oracle基本命令大全

    用户: scott/tiger sys as sysdba 空密码 转换用户登录: connect 用户/密码 connect sys as sysdba   权限 用户解锁: alter user ...

  10. django----对model查询扩展

    基于对象关联查询 一对多查询(Book--Publish): 正向查询,按字段: (从关联的表中查询) book_obj.publish : 与这本书关联的出版社对象 book_obj.publish ...