[rmq] Jzoj P5863 移动光标

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

代码

  • 一般的情况,当然移动的次数就是|x1-x2|+|y1-y2|
  • 那么考虑x1~x2中每行的长度的最小值,是小于y2的
  • 这样就不能直接走了,考虑从y1走到m,再走到y2

代码

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cmath>
 4 using namespace std;
 5 int n,q,x1,x2,y,y2,ans,f[100010][20];
 6 int getmin(int l,int r)
 7 {
 8     int len=r-l+1,k=trunc(log(len+0.5)/log(2));
 9     return min(f[l][k],f[l+len-(1<<k)][k]);
10 }
11 int main()
12 {
13     freopen("cusor.in","r",stdin);
14     freopen("cusor.out","w",stdout);
15     scanf("%d",&n);
16     for (int i=1;i<=n;i++) scanf("%d",&f[i][0]);
17     for (int j=1;j<20;j++)
18         for (int i=1;i<=n;i++)
19         {
20             f[i][j]=f[i][j-1];
21             if (i+(1<<j-1)<=n) f[i][j]=min(f[i][j],f[i+(1<<j-1)][j-1]);
22         }
23     scanf("%d",&q);
24     for (int i=1;i<=q;i++)
25     {
26         scanf("%d%d%d%d",&x1,&y,&x2,&y2);
27         if (x1>x2) swap(x1,x2),swap(y,y2);
28         int mn=getmin(x1,x2),ans=0;
29         if (y>mn) ans+=y-mn,y=mn;
30         if (y2>mn) ans+=y2-mn,y2=mn;
31         ans+=abs(y-y2)+(x2-x1);
32         printf("%d\n",ans);
33     }
34 }

猜你喜欢

转载自www.cnblogs.com/Comfortable/p/9649805.html
RMQ