排列的排名

B 排列
文件名 输入文件 输出文件 时间限制 空间限制
perm.pas/c/cpp perm.in perm.out 1s 128MB
题目描述
小 G 喜欢玩排列。现在他手头有两个 n 的排列。n 的排列是由 0,1,2,...,n − 1
这 n 的数字组成的。对于一个排列 p,Order(p) 表示 p 是字典序第 Order(p) 小的
排列(从 0 开始计数)。对于小于 n! 的非负数 x,Perm(x) 表示字典序第 x 小的排
列。
现在,小 G 想求一下他手头两个排列的和。两个排列 p 和 q 的和为 sum =
Perm((Order(p) + Order(q))%n!)。
输入格式
输入文件第一行一个数字 n,含义如题。
接下来两行,每行 n 个用空格隔开的数字,表示小 G 手头的两个排列。
输出格式
输出一行 n 个数字,用空格隔开,表示两个排列的和。
样例输入 1
2
0 1
1 0
样例输出 1
1 0
样例输入 2
3
1 2 0
2 1 0
3
样例输出 2
1 0 2
数据范围
1、2、3、4 测试点,1 ≤ n ≤ 10。
5、6、7 测试点,1 ≤ n ≤ 5000,保证第二个排列的 Order ≤ 10 5 。
8、9、10 测试点,1 ≤ n ≤ 5000。

思路:

  这是排列的排名问题。

  第一遍做我直接去算那个排名了,但大数据的话就需要用Rank数组来加减进位了

复制代码
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=5009;
int n;
int p[N],q[N];
int pp1[N],pp2[N],ans[N];
bool cnt[N];
int main()
{
    freopen("perm.in", "r", stdin);
    freopen("perm.out", "w", stdout);
    scanf("%d",&n);
    for(int i=n;i>=1;i--)    scanf("%d",&p[i]);
    for(int i=n;i>=1;i--)    scanf("%d",&q[i]);
    
    for(int i=1;i<=n;i++)
    for(int j=1;j<i;j++)
        pp1[i]+=(bool)(p[i]>p[j]);
    for(int i=1;i<=n;i++)
    for(int j=1;j<i;j++)
        pp2[i]+=(bool)(q[i]>q[j]);
    
    for(int i=2;i<=n;i++)
    {
        ans[i]+=pp1[i]+pp2[i];
        ans[i+1]+=(ans[i])/i;
        ans[i]%=i;
    }
    
    for(int i=n;i>=1;i--)
    {
        int sum=-1;
        while(ans[i]>=0)
        {
            sum++;
            if(!cnt[sum]) ans[i]--;
        }
        printf("%d ",sum);
        cnt[sum]=1;
    }
    return 0;
}
复制代码

 

posted @   浪矢-CL  阅读(347)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示