zoukankan      html  css  js  c++  java
  • [cf1097E]Egor and an RPG game

    构造形如$1,3,2,6,5,4,10,9,8,7,...$的序列,不难发现其中前$frac{k(k+1)}{2}$项最少要划分为$k$个单调子序列

    由此,取$k=f(n)+1$时应有$frac{k(k+1)}{2}>n$,也即有$f(n)ge max_{frac{k(k+1)}{2}le n}k$

    令$g(n)$为后者,那么只需要保证划分为不超过$g(n)$个单调子序列即可

    考虑其最长上升子序列,假设长度为$x$,对其分类讨论:

    1.若$xge g(n)+1$,则有$g(n-x)+1le g(n)$,那么直接选择该序列即可

    关于这个式子,即求证$frac{g(n)(g(n)+1)}{2}>n-(g(n)+1)$,化简后也即$frac{(g(n)+1)(g(n)+2)}{2}>n$,那么如果其不满足即与$g(n)$的最大性矛盾

    2.若$xle g(n)$,注意到原序列可以被划分为$x$个下降子序列,直接划分为下降子序列即可

    直接暴力即可,注意到$g(n)$是$o(sqrt{n})$级别的,复杂度为$o(nsqrt{n}log n)$

    对于这个复杂度,如果$log$是线段树复杂度可能无法通过,需要使用经典的dp+二分求LIS,下面来分别考虑两种序列如何划分——

    对于最长上升子序列,记录每一个数字插入时上一个位置的数字,往前找即可

    对于下降子序列,注意到每一个位置上的数都单调递增,即分别构成一个下降子序列

    总复杂度为$o(nsqrt{n}log n)$,且常数较小,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100005
     4 #define ll long long
     5 vector<int>ans[N];
     6 int t,n,m,tot,a[N],val[N],Pos[N],pre[N],fi[N],nex[N],vis[N];
     7 int main(){
     8     scanf("%d",&t);
     9     while (t--){
    10         scanf("%d",&n);
    11         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    12         m=0;
    13         while (n){
    14             tot=0;
    15             for(int i=1;i<=n;i++){
    16                 int pos;
    17                 if ((!tot)||(val[tot]<a[i])){
    18                     pos=++tot;
    19                     fi[pos]=i;
    20                 }
    21                 else{
    22                     pos=lower_bound(val+1,val+tot+1,a[i])-val;
    23                     nex[Pos[pos]]=i;
    24                 }
    25                 val[pos]=a[i],Pos[pos]=i;
    26                 if (pos==1)pre[i]=0;
    27                 else pre[i]=Pos[pos-1];
    28             }
    29             if ((ll)tot*(tot+1)/2<=n){
    30                 for(int i=1;i<=tot;i++){
    31                     ans[++m].clear();
    32                     for(int j=fi[i];j!=Pos[i];j=nex[j])ans[m].push_back(a[j]);
    33                     ans[m].push_back(a[Pos[i]]);
    34                 }
    35                 break;
    36             }
    37             ans[++m].clear();
    38             for(int i=1;i<=n;i++)vis[i]=0;
    39             for(int i=Pos[tot];i;i=pre[i])vis[i]=1;
    40             int nn=0;
    41             for(int i=1;i<=n;i++){
    42                 if (!vis[i])a[++nn]=a[i];
    43                 else ans[m].push_back(a[i]);
    44             }
    45             n=nn;
    46         }
    47         printf("%d
    ",m);
    48         for(int i=1;i<=m;i++){
    49             printf("%d",ans[i].size());
    50             for(int j=0;j<ans[i].size();j++)printf(" %d",ans[i][j]);
    51             printf("
    ");
    52         }
    53     }
    54     return 0;
    55 } 
    View Code
  • 相关阅读:
    springboot-6-整合jdbc
    springboot-4-整合fastjson
    Python决策树可视化:GraphViz's executables not found的解决方法
    pandas的行列显示不全的解决方法
    3(1).特征选择---过滤法(特征相关性分析)
    3(2).特征选择---包装法
    seaborn矩阵图组合图---热力图heatmap、聚类图clustermap
    3(3).特征选择---嵌入法(特征重要性评估)
    datetime,Timestamp和datetime64之间转换
    Spring配置文件总结
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15225228.html
Copyright © 2011-2022 走看看