zoukankan      html  css  js  c++  java
  • 多校第8场 hdu6406 Taotao Picks Apples 单调栈+主席树

    题目连接:Taotao Picks Apples

    题意:给一个数列,然后替换掉一个数,求从左开始的严格递增序列长度(第一个必选)

    题解:先预习处理前缀最大值和到这里的长度,在用单调栈处理出从i这里开始的递增序列长度。然后从n~1倒着建立主席树维护区间的最小下标。这样就可以询问后面开始的最小位置,对于每次询问反过来注意一下细节就可以了。

     1 #include<bits/stdc++.h>
     2 #define eps 1e-10;
     3 using namespace std;
     4 const int N = 1e5+7,M=6000005;
     5 
     6 int h[N],n,m;
     7 int mx[N],w[N],len[N];//前缀最大值,1到i递增序列长度,i到n的递增序列长度
     8 int que[N],ed,top,fa[N],pp[N];//队列,栈底,栈顶,fa[i]下一个比i大的位置,pp[i]表示1~i递增序列的最后一个下标
     9 int ls[M],rs[M],mi[M],rt[N],tot,sz;//左右儿子,位置,
    10 void init()
    11 {
    12     tot=ed=top=0;
    13 }
    14 void update(int &o,int pre,int l,int r,int x,int  p)
    15 {
    16     o=++tot;ls[o]=ls[pre];rs[o]=rs[pre];
    17     mi[o]=min(mi[pre],p);
    18     if(l==r)return;
    19     int m=(l+r)>>1;
    20     if(x<=m) update(ls[o],ls[pre],l,m,x,p);
    21     else update(rs[o],rs[pre],m+1,r,x,p);
    22 }
    23 int query(int rt,int l,int r,int p)
    24 {
    25     if(!rt||p>r)return n+1;
    26     if(p<=l)return mi[rt];
    27     int m=(l+r)>>1;
    28     if(p<=m)return min(query(ls[rt],l,m,p),query(rs[rt],m+1,r,p));
    29     return query(rs[rt],m+1,r,p);
    30 }
    31 int main(){
    32     int T;
    33     scanf("%d",&T);
    34     while(T--)
    35     {
    36         init();
    37         scanf("%d %d",&n,&m);
    38         for(int i=1;i<=n;i++)
    39         {
    40             scanf("%d",&h[i]);
    41         }
    42         for(int i=1;i<=n;i++)
    43         {
    44             if(h[i]>mx[i-1])
    45             {
    46                 mx[i]=h[i]; w[i]=w[i-1]+1; pp[i]=i;
    47             }
    48             else
    49             {
    50                 mx[i]=mx[i-1];w[i]=w[i-1]; pp[i]=pp[i-1];
    51             }
    52         }
    53         for(int i=n;i>=1;i--)
    54         {
    55             while(top>ed&&h[que[top]]<=h[i])top--;
    56             que[++top]=i;
    57             len[i]=top-ed;
    58              if(top-ed>1)fa[i]=que[top-1];
    59             else fa[i]=n+1;
    60         }
    61         mi[0]=n+1;rt[n+1]=0;len[n+1]=0;
    62         for(int i=n;i>=1;i--)
    63         {
    64             update(rt[i],rt[i+1],1,1e9,h[i],i);
    65         }
    66         while(m--)
    67         {
    68             int p,x;
    69             scanf("%d %d",&p,&x);
    70             if(p==1)
    71             {
    72                  printf("%d
    ",1+len[query(rt[p+1],1,1e9,x+1)]);
    73             }
    74             else
    75             {
    76                 int pre=pp[p-1];
    77                 if(fa[pre]==p)
    78                 {
    79                     if(x>h[pre])printf("%d
    ",w[p]+len[query(rt[p+1],1,1e9,x+1)]);
    80                     else printf("%d
    ",w[pre]+len[query(rt[p+1],1,1e9,h[pre]+1)]);
    81                 }
    82                 else
    83                 {
    84                     if(x>h[pre])printf("%d
    ",1+w[p]+len[query(rt[p+1],1,1e9,x+1)]);
    85                     else printf("%d
    ",w[n]);
    86                 }
    87             }
    88         }
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    JS中的继承(上)
    一篇文章理解JS继承——原型链/构造函数/组合/原型式/寄生式/寄生组合/Class extends
    JS 装饰器,一篇就够
    理解 JavaScript 的 async/await
    JS正则表达式入门,看这篇就够了
    JavaScript的几种循环方式
    全解跨域请求处理办法
    下班后的时间精力生活管理办法(时间管理)
    hexo上部署博客到Github失败
    11
  • 原文地址:https://www.cnblogs.com/lhclqslove/p/9487717.html
Copyright © 2011-2022 走看看