zoukankan      html  css  js  c++  java
  • [nowcoder5668I]Sorting the Array

    令$f(n,b,m)=a[1..n]$(这里下标从1开始),考虑一些性质:
    性质1.对于$forall 1le ile n-m+1$,若$exists 1le j<i,a[j]>a[i]$,那么有$b[i+m-1]=a[i]$,证明略
    根据性质1,可以去除掉所有满足条件的$i$,那么$a$就满足单调上升
    性质2.对于$forall 1le ile n$,都有$a[i]=f(j,b,j)[i]$,其中$j=min(i+m-1,n)$(归纳法即可证)
    根据性质2,容易发现$a_{i}$合法当且仅当其填在$b[1..j]$中,即$b$的方案数为$prod_{i=1}^{n}min(m,n-i+1)$
    找到1个最大的$x$满足$prod_{i=x}^{n}min(m,n-i+1)ge k$,那么$forall 1le i<x$,直接将$a_{i}$填在b中最小的未被填过的位置即可,而由于$mge 2$,所以有$n-xge log_{2}k$,即仅需要考虑后$lceil log_{2}k ceil+1$个位置,那么不断枚举当前位置上的数并判断:1.剩余方案数是否不小于k;2.这个位置上的数是否有限制(即填完后要保证$a[i-m+1]$的已填过了)
    考虑时间复杂度,由于是多组数据,那么复杂度为$o(nlog_{2}^{ 2}k)$,可以通过优化降为$o(nlog_{2}k)$
     
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 800005
     4 int t,n,m,x,a[N],b[N],id[N],vis[N],ans[N];
     5 long long k;
     6 int main(){
     7     scanf("%d",&t);
     8     while (t--){
     9         scanf("%d%d%lld",&n,&m,&k);
    10         int s=0,nn=0;
    11         for(int i=1;i<=n;i++)ans[i]=0;
    12         for(int i=1,j=1;i<=n;i++){
    13             scanf("%d",&x);
    14             if (s>x)ans[i+m-1]=x;
    15             else{
    16                 s=a[++nn]=x;
    17                 while (ans[j])j++;
    18                 id[nn]=j++;
    19             }
    20         }
    21         int las=nn;
    22         long long sum=1;
    23         while (sum<k){
    24             las--;
    25             sum*=min(nn-las+1,m);
    26         }
    27         for(int i=1;i<las;i++)ans[id[i]]=a[i];
    28         for(int i=las;i<=nn;i++){
    29             vis[i]=0;
    30             b[i]=min(nn-i+1,m);
    31         }
    32         for(int i=las;i<=nn;i++)
    33             for(int j=las;j<=nn;j++)
    34                 if (!vis[j]){
    35                     sum=sum/(b[j]--);
    36                     if (k<=sum){
    37                         vis[j]=1;
    38                         ans[id[i]]=a[j];
    39                         break;
    40                     }
    41                     k-=sum;
    42                     sum*=b[j];
    43                 }
    44         for(int i=1;i<=n;i++)printf("%d ",ans[i]);
    45         printf("
    ");
    46     }
    47 }
    View Code
  • 相关阅读:
    MySQL用户信息表中主键userID自动增加问题
    PHP输出当前系统时间
    PHP连接MySQL方式比较问题
    DWZ分页处理
    NHibernate ICriteria 查询[转 十年如一]
    HttpContext.Current.Request.Files后台取不到值的解决方法 [转]
    Hibernate Projections(投影、统计、不重复结果)[转]
    细说Form(表单)[ 转 Fish Li]
    HTML <a> 标签的 rel 属性
    dwz rel
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13390009.html
Copyright © 2011-2022 走看看