题意:
给你下雨量,让你判断每一句话是否正确
题解:
线段树
用来维护判断
代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int N=400005; struct seg { int max; }tree[N]; int n,m,x[N],y[N],sum[N]; void build(int rt,int L,int R) { if (L==R) { tree[rt].max=y[L]; return; } int mid=(L+R)>>1; build(rt<<1,L,mid); build((rt<<1)+1,mid+1,R); tree[rt].max=max(tree[rt<<1].max,tree[(rt<<1)+1].max); } int query(int rt,int L,int R,int QL,int QR) { if (QL>R||QR<L) return -2e9; if (QL<=L&&QR>=R) return tree[rt].max; int mid=(L+R)>>1; return max(query(rt<<1,L,mid,QL,QR), query((rt<<1)+1,mid+1,R,QL,QR)); } int find(int X) { int L=1,R=n,mid; while (L<=R) { mid=(L+R)>>1; if (x[mid]==X) return mid; if (x[mid]>X) R=mid-1; if (x[mid]<X) L=mid+1; } return -1; } int find_2(int X) { int L=1,R=n,mid,res; while (L<=R) { mid=(L+R)>>1; if (x[mid]>X) res=mid,R=mid-1; else L=mid+1; } return res; } int find_3(int X) { int L=1,R=n,mid,res; while (L<=R) { mid=(L+R)>>1; if (x[mid]<X) res=mid,L=mid+1; else R=mid-1; } return res; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]); build(1,1,n); scanf("%d",&m); for (int i=1,x1,x2,bh1,bh2;i<=m;i++) { scanf("%d%d",&x1,&x2); if (!(x1<x2)) { puts("false"); continue; } bh1=find(x1),bh2=find(x2); if (bh1==-1 && bh2==-1) { puts("maybe"); continue; } if (bh2==-1) { bh2=find_3(x2); if (bh1+1>bh2||query(1,1,n,bh1+1,bh2)<y[bh1]) puts("maybe"); else puts("false"); continue; } if (bh1==-1) { bh1=find_2(x1); if (bh1>bh2-1||query(1,1,n,bh1,bh2-1)<y[bh2])puts("maybe"); else puts("false"); continue; } if (!(y[bh1]>=y[bh2])) { puts("false"); continue; } if (bh1+1>bh2-1||query(1,1,n,bh1+1,bh2-1)<y[bh2]) if (x2-x1==bh2-bh1)puts("true"); else puts("maybe"); else puts("false"); } return 0; }