ICPC NEAU Programming Contest 2020 D 旅游(单调栈+倍增)

链接 :D 旅游
ICPC NEAU Programming Contest 2020 D 旅游(单调栈+倍增)_第1张图片

思路
单调栈处理出每个点右边第一个大于它的点,然后倍增跳 yi 次,和 倍增lca 类似 从一个点一个点跳 变成倍增跳(全用下标处理)。

代码:

#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll ;
const int maxn=1e5+7;
int t,a[maxn],f[maxn][32],n,m;
stack < int >s;
void rmq(){
     for(int j = 0; (1 << (j + 1)) < n; j++){
        for(int i = 1; i <= n; i++){
            if(f[i][j]==0) f[i][j + 1] = 0;
            else f[i][j + 1] = f[f[i][j]][j];
        }
     }
}
int main (){
    cin>>t;
    while(t--){
         cin>>n>>m;
         while(s.size()) s.pop();
         memset(f,0,sizeof(f));
         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
         for(int i=1;i<=n;i++){
             if(s.size()==0||a[s.top()]>=a[i]){
                s.push(i);
             }
             else{
                 while(s.size()&&a[i]>a[s.top()]){
                      f[s.top()][0]=i;
                      s.pop();
                 }
                 s.push(i);
             }
         }
         rmq();
         while(m--){
              int u,v;
              scanf("%d%d",&u,&v);
              v--;
              for(int i=0;i<18;i++){
                  if((v>>i)&1) u=f[u][i];
              }
              if(u) printf ("%d\n",u);
              else printf ("-1\n");
         }
    }
}

你可能感兴趣的:(ICPC NEAU Programming Contest 2020 D 旅游(单调栈+倍增))