zoukankan      html  css  js  c++  java
  • COGS2485 从零开始的序列

    传送门

    题意:给定一个长为$n$的序列,定义$f(x)$表示所有(长为$x$的区间最小值)的最大值,求$f(1)$~$f(n)$。

    看好多人都用并查集做的,然而我并不想写……既然品酒大会可以后缀数组+并查集也可以直接用后缀树递推,那这个问题直接上树再递推也行吧……

    跟RMQ有关的一个树形结构就是笛卡尔树,那么我们构建笛卡尔树后自底向上递推一遍即可,对每个节点更新它对应区间长度的答案,最后根据$f(x)ge f(x+1)$更新一遍所有的$f$即可。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int maxn=200010;
     6 void bfs();
     7 int n,a[maxn],f[maxn],root,lc[maxn]={0},rc[maxn]={0},s[maxn],top=0,q[maxn],size[maxn]={0};
     8 int main(){
     9     freopen("sky_seq.in","r",stdin);
    10     freopen("sky_seq.out","w",stdout);
    11     memset(f,-63,sizeof(f));
    12     scanf("%d",&n);
    13     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    14     s[++top]=root=1;
    15     for(int i=2;i<=n;i++){
    16         s[top+1]=0;
    17         while(a[i]<a[s[top]])top--;
    18         if(top)rc[s[top]]=i;
    19         else root=i;
    20         lc[i]=s[top+1];
    21         s[++top]=i;
    22     }
    23     bfs();
    24     for(int i=n;i;i--)f[i]=max(f[i],f[i+1]);
    25     for(int i=1;i<=n;i++)printf("%d ",f[i]);
    26     return 0;
    27 }
    28 void bfs(){
    29     int x,head=1,tail=1;
    30     q[tail++]=root;
    31     while(head!=tail){
    32         x=q[head++];
    33         size[x]=1;
    34         if(lc[x])q[tail++]=lc[x];
    35         if(rc[x])q[tail++]=rc[x];
    36     }
    37     for(int i=n;i;i--){
    38         x=q[i];
    39         size[x]+=size[lc[x]]+size[rc[x]];
    40         f[size[x]]=max(f[size[x]],a[x]);
    41     }
    42 }
    View Code

    lyc说这个题是从CF上搬过来的,然而他也忘了是哪道题了……麻烦知道的dalao在评论里告诉我一声……

  • 相关阅读:
    express配置流程(windows)
    web性能优化
    解决“向终端显示内容产生时间延迟”
    node.js全局配置
    BootStrap基本模板
    移动Web开发小结
    理解一下vue的mvvm模式
    前端面试题
    使用layui遇到的一些问题及解决方案
    Vue之使用ajax获取json数据,并用v-for循环显示在表格中
  • 原文地址:https://www.cnblogs.com/hzoier/p/6488703.html
Copyright © 2011-2022 走看看