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

题目描述

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. mysql案例~关于mysql的配置文件个人见解

    mysql 设置参数解读一  mysql的参数分为几类     1 session级别可以设置     2 global级别可以设置     3 session+global级别可以设置     4 ...

  2. 图片的Base64编码

    Base64编码是一种图片处理格式,通过特定的算法将图片编码成一长串字符串,在页面上显示的时候,可以用该字符串来代替图片的url属性. 我们可以来看一下实际的效果 Base64编码效果 在上图中,我们 ...

  3. 2018-2019-2 网络对抗技术 20165227 Exp4 恶意代码分析

    2018-2019-2 网络对抗技术 20165227 Exp4 恶意代码分析 实验步骤: 使用的设备:Win7(虚拟机).kali(虚拟机) 实验一:使用如计划任务,每隔一分钟记录自己的电脑有哪些程 ...

  4. Netty通信原理

    Netty是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端,它极大的简化了TCP和UDP套接字服务器等网络编程. BIO(Blocking IO):每一个请求,一个S ...

  5. ARMV8 datasheet学习笔记4:AArch64系统级体系结构之存储模型

    1.前言 关于存储系统体系架构,可以概述如下: 存储系统体系结构的形式 VMSA 存储属性   2. 存储系统体系结构 2.1.    地址空间 指令地址空间溢出 指令地址计算((address_of ...

  6. 再谈:自定义结构体的对齐问题之__attribute__ ((packed))方法【转】

    转自:https://blog.csdn.net/ipromiseu/article/details/5955295 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.c ...

  7. 如何在linux下检测内存泄漏(转)

    本文转自:http://www.ibm.com/developerworks/cn/linux/l-mleak/ 本文针对 linux 下的 C++ 程序的内存泄漏的检测方法及其实现进行探讨.其中包括 ...

  8. Linux系统打开core dump的配置【转】

    什么是core dump core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump.core du ...

  9. 记录entityframework生成的sql语句

    Interceptors (EF6.1 Onwards) Starting with EF6.1 you can register interceptors in the config file. I ...

  10. adb启动和停止android app方法

    一.启动app adb shell am start  包名/MainActivity 上面涉及到的包名及mainactivity获取办法 方法一: 1.adb shell 2.dumpsys act ...