一个简单的线段树维护最值,容易犯错的地方在于y相等的时候不应该省略 这个地方调了一会发现自己傻了
#include<bits/stdc++.h>
#define ls u<<1
#define rs u<<1|1
using namespace std;
const int N = 1e5+10;
typedef long long ll;
const ll INF = 2e18;
struct Tree{
int l,r;
ll mmin,mmax;
}tr[N*4];
int n,m;
vector<ll>vecx;
struct Node{
int x,y;
}node[N];
void pushup(int u){
tr[u].mmin = min(tr[u<<1].mmin,tr[u<<1|1].mmin);
tr[u].mmax = max(tr[u<<1].mmax,tr[u<<1|1].mmax);
}
void build(int u,int l,int r){
tr[u] = {l,r,INF,-INF};
if(l==r)return;
int mid = l+r>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
pushup(u);
}
ll query1(int u,int l,int r){
if(l<=tr[u].l&&r>=tr[u].r)return tr[u].mmin;
int mid = tr[u].l+tr[u].r>>1;
ll res = INF;
if(l<=mid)res = min(res,query1(u<<1,l,r));
if(r>mid)res = min(res,query1(u<<1|1,l,r));
return res;
}
ll query2(int u,int l,int r){
if(l<=tr[u].l&&r>=tr[u].r)return tr[u].mmax;
int mid = tr[u].l+tr[u].r>>1;
ll res = -INF;
if(l<=mid)res = max(res,query2(u<<1,l,r));
if(r>mid)res = max(res,query2(u<<1|1,l,r));
return res;
}
int findx(int x){
return lower_bound(vecx.begin(),vecx.end(),x)-vecx.begin()+1;
}
void modify(int u,int x, ll c){
if(tr[u].l == tr[u].r){
tr[u].mmin = min(tr[u].mmin,c);
tr[u].mmax = max(tr[u].mmax,c);
return;
}
int mid = tr[u].l+tr[u].r>>1;
if(x<=mid)modify(ls,x,c);
else modify(rs,x,c);
pushup(u);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
int x,y;
cin>>x>>y;
node[i]={x,y};
vecx.push_back(x);
}
sort(vecx.begin(),vecx.end());
vecx.erase(unique(vecx.begin(),vecx.end()),vecx.end());
build(1,1,100010);
for(int i=1;i<=n;i++){
int x = findx(node[i].x);
modify(1,x,node[i].y);
}
int m;
cin>>m;
while(m--){
int id1,id2;
cin>>id1>>id2;
auto t1 = node[id1];
auto t2 = node[id2];
int x_1 = findx(t1.x);
int x_2 = findx(t2.x);
if(x_1>=x_2)printf("0\n");
else{
ll len = query2(1,x_1,x_2)-query1(1,x_1,x_2);
ll s = len * abs(t1.x-t2.x);
printf("%lld\n",s);
}
}
return 0;
}