1. 程式人生 > >jzoj 5863. 【NOIP2018模擬9.11】移動游標 rmq

jzoj 5863. 【NOIP2018模擬9.11】移動游標 rmq

Description 這裡寫圖片描述

Input 這裡寫圖片描述

Output 這裡寫圖片描述

Sample Input 4 3 2 4 3 3 1 1 3 2 3 3 4 2 1 3 3 4

Sample Output 3 2 5

Data Constraint 這裡寫圖片描述

分析: 其實可以得到這中間所有的串長度最小值,然後討論一下。 最小值可以用rmq求。

程式碼:

#include <iostream>
#include <cmath>
#include <cstdio>

const int maxn=1e5+7;

using namespace
std; int n,q,l,r,x,y,ans; int f[maxn][20]; int getmin(int l,int r) { int len=r-l+1; int k=trunc(log(len+0.5)/log(2)); return min(f[l][k],f[l+len-(1<<k)][k]); } int main() { freopen("cusor.in","r",stdin); freopen("cusor.out","w",stdout); scanf("%d",&n); for (int
i=1;i<=n;i++) scanf("%d",&f[i][0]); int k=1; for (int j=1;j<20;j++) { for (int i=1;i<=n;i++) { f[i][j]=f[i][j-1]; if (i+k<=n) f[i][j]=min(f[i][j],f[i+k][j-1]); } k*=2; } scanf("%d",&q); for (int i=1;i<=q;i++) { scanf
("%d%d%d%d",&l,&x,&r,&y); if (l>r) swap(l,r),swap(x,y); ans=0; int d=getmin(l,r); if (x>d) ans+=x-d,x=d; if (y>d) ans+=y-d,y=d; ans+=abs(x-y)+(r-l); printf("%d\n",ans); } }