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

题目描述

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. Database学习 - mysql 数据库 外键

    外键 外键约束子表的含义:如果在父表中赵达不到候选键,则不允许在子表上进行insert/update 外键预约对父表的含义:在父表上进行update/delete以更新或删除子表中有一条或多条对应匹配 ...

  2. ES系列十六、集群配置和维护管理

    一.修改配置文件 1.节点配置 1.vim elasticsearch.yml # ======================== Elasticsearch Configuration ===== ...

  3. mysql系列七、mysql索引优化、搜索引擎选择

    一.建立适当的索引 说起提高数据库性能,索引是最物美价廉的东西了.不用加内存,不用改程序,不用调sql,只要执行个正确的'create index',查询速度就可能提高百倍千倍,这可真有诱惑力.可是天 ...

  4. mysql安装与卸载(非绿色版)

    一.安装和卸载 Mysql安装路径: C:\Program Files\MySQL\MySQL Server 5.5\ Mysql数据文件存放的路径: C:\Documents and Setting ...

  5. vim常用

    删除空行 :g@^$@d

  6. Java基础99 待续

    1.待续 原创作者:DSHORE 作者主页:http://www.cnblogs.com/dshore123/ 原文出自:https://www.cnblogs.com/dshore123/p/107 ...

  7. Win7 x64 svn 服务器搭建

    SVN服务器搭建和使用   Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网站上了 ...

  8. python3之MongoDB

    1.MongoDB简介 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统. 在高负载的情况下,添加更多的节点,可以保证服务器性能. MongoDB 旨在为WEB应用提供可 ...

  9. __dirname与__filename

    (1) __filename变量 node.js中,在任何模块文件内部,可以使用__filename变量获取当前模块文件的带有完整绝对路径的文件名. 在应用程序根目录下新建app.js文件,其中代码如 ...

  10. java 类字面常量,泛化的Class引用

    类名.class 就是字面常量,代表的就是该类的Class对象引用.常量需要赋值给变量 简单,安全. 编译期接受检查,不需要像forName一样置于try/catch块中. 加载后不会进行初始化,初始 ...