zoukankan      html  css  js  c++  java
  • Luogu T10025 排列名次

    题目链接

    题目描述

    给定一个长度为n的排列,要求输出该排列的字典序名次(1,2,3,...,n的名次为1)。

    输入输出格式

    输入格式:

    第一行一个数n,表示排列长度。

    第二行n个数,用空格分隔,表示一个长度为n的排列。

    输出格式:

    一个数,表示该排列的字典序名次。由于答案可能很大,请输出答案对1e9+7取模后的结果。

    输入输出样例

    输入样例#1:
    9
    9 8 7 6 5 4 3 1 2
    输出样例#1:
    362879

    说明

    对于30%的数据,n<=10。

    对于100%的数据,n<=100000。

    题解:

    30分做法:纯暴力。枚举名次从1至n!的排列,并与给定排列相比较。复杂度O(n!)。

    100分做法:类康托展开。

    下面进入精彩的猜结论推理时间:

    以排列5 9 7 6 8 1 4 3 2为例,第一个数字是5,在5之前还有1,2,3,4,一共4个数字没有用过,脑中模拟暴力过程推理可知以5开头的第一个排列的序号应为1+4*8!。第二个数字是9,在9之前还有1,2,3,4,6,7,8,一共7个数字没有用过,同理可知以59开头的第一个排列的序号为1+4*8!+7*7!。如此递推下去即可得到给定排列的序号。

    所以本题需要预处理出1至n的阶乘,还需要得知排列中第i个数之后有多少个数比自己小。这个可以用树状数组维护前缀和得到:初始时每个元素都是1,处理至排列a时查询sum(a[i]-1),然后add(a[i],-1)即可。

    预处理O(n),依次处理每个元素为O(n),每次处理时sum和add操作为O(logn),总复杂度O(nlogn)。

    代码:

    #include<bits/stdc++.h>
    #define LL long long
    #define lowbit(x) x&(-x)
    using namespace std;
    const int maxn=1e5+10,MOD=1e9+7;
    int a[maxn],c[maxn];
    LL fac[maxn],ans=1;
    int n;
    void add(int x,int d)
    {
       int i;
       for(i=x;i<=n;i+=lowbit(i)){c[i]+=d;}
    }
    int sum(int x)
    {
       int i,ans=0;
       for(i=x;i>=1;i-=lowbit(i)){ans+=c[i];}
       return ans;
    }
    int main()
    {
       int i,j;LL tmp;
       //freopen("data9.in","r",stdin);
       //freopen("data9.out","w",stdout);
       cin>>n;fac[0]=1;
       for(i=1;i<=n;i++){fac[i]=i*fac[i-1]%MOD;add(i,1);}
       for(i=1;i<=n;i++){scanf("%d",&a[i]);}
       //for(i=0;i<=n;i++){cout<<sum(i)<<" ";}cout<<endl;
       for(i=1;i<=n;i++)
       {
          tmp=sum(a[i]-1)*fac[n-i]%MOD;
          //printf("i=%d sum(a[i]-1)=%d fac[n-i]=%d tmp=%d ans=%d ",i,sum(a[i]-1),fac[n-i],tmp,ans);
          ans=(ans+tmp)%MOD;
          add(a[i],-1);
       }
       cout<<ans<<endl;
       return 0;
    }

  • 相关阅读:
    J2SE-反射
    c3p0 连接数据库失败的问题
    c# 调用存储过程
    存储过程使用truncate时
    Parcelable intent传递对象时,需要将该对象实现Parcelable 或者Serializable
    android intent 在打开设置activity的时候在监听事件的内部 适用setclass()方法时 不是直接适用this 关键字
    c# 读取appconfig文件
    Oracle 连接数据库的几种方式
    通过反射获得方法,和绑定事件
    js 验证
  • 原文地址:https://www.cnblogs.com/XSC637/p/7424871.html
Copyright © 2011-2022 走看看