• Permutation


    Permutation

    日照夏令营D2T2,赛场上40分,因为当时用的阶乘把康托展开算出来了,由于n很大,后6个点爆了。其实不用算,比如a是第x个排列,b是第y个排列,而想xy能拆成rank数组,x+y实际上就是它们对应位上rank数组的值相加,因为最后要求的是排列,所以根本用不到阶乘。这里用的是类似高精度的加法,当然也要进位,对于某一个位,假设为(x+3)*x!,

    则进位时对应系数要减(x+1),即(x+1!+2*x!,为什么要进位呢?阶乘前的系数表示比当前位小的还未出现的数的个数,阶乘本身代表的是全排列,即剩下多位置可以放数,如果系数大于阶乘的数字,就放不开了,证毕。

    //ktzk
    
    #include<bits/stdc++.h>
    using namespace std;
    int n;
    int r1[5010];
    int r2[5010];
    int r3[5010];
    int a[5010];
    int b[5010];
    bool a1[5010];
    bool b1[5010];
    bool c[5010];
    int ans[5010];
    
    void kta()
    {
      int cnt=0;
      int j;
      for(int i=0;i<n;i++)
      {
          for(j=0;j<n;j++)
          if(j<a[i]&&a1[j]==false) 
          cnt++;
          a1[a[i]]=true;
        r1[i]=cnt;
        cnt=0;
      }    
    }
    
    void ktb()
    {
      int cnt=0;
      int j;
      for(int i=0;i<n;i++)
      {
          for(j=0;j<n;j++)
          if(j<b[i]&&b1[j]==false) 
          cnt++;
          b1[b[i]]=true;
        r2[i]=cnt;
        cnt=0;
      }    
    }
    
    void sum()
    {
        int len=0;
        bool t=false;
        for(int i=n-1;i>=0;i--)
        {
          r3[len]+=r1[i]+r2[i];
          while(r3[len]>len)
          {
            r3[len]-=(len+1);
            r3[len+1]++;    
            t=true;
          }
          len++;
        }
    }
    
    void fkt()
    {
        int cnt=0;
        int j;
        for(int i=n-1;i>=0;i--)
        {
            for(j=0;j<n;j++)
            {
            if(c[j]==false&&cnt<r3[i]) cnt++;
            else
            if(c[j]==false)
            {
                ans[i]=j;    
             c[j]=true;
             cnt=0;
            break;
            }
            }
            
        }
    }
    
    int main()
    {
        freopen("perm.in","r",stdin);
        freopen("perm.out","w",stdout);
        cin>>n;
        for(int i=0;i<n;i++) cin>>a[i];
        for(int i=0;i<n;i++) cin>>b[i];
        kta();    
        ktb();    
        sum();
        fkt();
        for(int i=n-1;i>=0;i--)
        cout<<ans[i]<<' ';
        return 0;
    }
  • 相关阅读:
    mysql高级之编程优化
    高性能产品必由之路
    linux下安装xhprof
    linux下安装apc
    linux下安装vld
    python装饰器通俗易懂的解释!
    python函数基础 与文件操作
    python基础入门一(语法基础)
    iOS Keychain,SSKeychain,使用 理解 原理
    起头
  • 原文地址:https://www.cnblogs.com/war1111/p/7348676.html
Copyright © 2020-2023  润新知