• loj2395 [JOISC 2017 Day 2]火车旅行


    传送门

    分析

    我们知道无论往左走还是往右走一定都是往不低于这个点的地方走

    于是我们可以考虑用倍增来维护一个点向左和向右走$2^i$最远分别能走到哪里

    我们可以先用单调栈求出直走一步的情况,之后再处理倍增数组

    值得注意的是有可能一直往左走不是最优情况,而先向右再想左会使答案更优

    于是le[x][i]=min(le[le[x][i-1]][i-1],le[ri[x][i-1]][i-1])

    向右的情况同理

    于是我们进一步考虑如何通过倍增数组得到答案、

    我们先从左面往右走,只要走$2^i$不会超过右节点则就让它走这么多步

    一直走到不能再走之后再从右往左走

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    const int LOG = 18;
    int a[100100],le[100100][LOG+3],ri[100100][LOG+3],st[100100],top;
    int main(){
        int n,m,i,j,k;
        scanf("%d%d%d",&n,&k,&m);
        for(i=1;i<=n;i++)scanf("%d",&a[i]);
        top=0;
        st[0]=1;
        for(i=1;i<=n;i++){
          while(top&&a[st[top]]<a[i])top--;
          le[i][0]=st[top];
          st[++top]=i;
        }
        top=0;
        st[0]=n;
        for(i=n;i>0;i--){
          while(top&&a[st[top]]<a[i])top--;
          ri[i][0]=st[top];
          st[++top]=i;
        }
        for(i=1;i<=LOG;i++)
          for(j=1;j<=n;j++){
            le[j][i]=min(le[le[j][i-1]][i-1],le[ri[j][i-1]][i-1]);
            ri[j][i]=max(ri[ri[j][i-1]][i-1],ri[le[j][i-1]][i-1]);
          }
        while(m--){
          int x,y,Ans=0,L,R,tl,tr;
          scanf("%d%d",&x,&y);
          if(x>y)swap(x,y);
          L=R=x;
          for(i=LOG;i>=0;i--){
              tl=min(le[L][i],le[R][i]);
              tr=max(ri[L][i],ri[R][i]);
              if(tr<y){
                L=tl,R=tr;
                Ans+=(1<<i);
              }
          }
          x=R;
          L=R=y;
          for(i=LOG;i>=0;i--){
              tl=min(le[L][i],le[R][i]);
              tr=max(ri[L][i],ri[R][i]);
              if(tl>x){
                L=tl,R=tr;
                Ans+=(1<<i);
              }
          }
          printf("%d
    ",Ans);
        }
        return 0;
    }
  • 相关阅读:
    SINAMICS S120/S120 EPOS 基本定位修改方向
    西门子 SINAMICS S120 Web server 用户名和默认密码
    在windows bat脚本(batch)中延时
    ubuntu修改字体大小
    python从字符串中提取数字,使用正则表达式
    python读入文档中的一行
    C++控制台暂停
    在ubuntu linux下安装*.sh的方法
    anaconda和jupyter notebook使用方法
    word禁止自动编号
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9913163.html
Copyright © 2020-2023  润新知