f[i][j]代表以i为左端点,选择2^j条线段,右端点最远能覆盖到哪,注意初始化时f[i]不具有单调性,要与f[i-1]取个max。
#include<bits/stdc++.h> #define file(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout); #define P 998244353 #define mid (l+r>>1) #define N 2100000 #define lb(x) (x&(-x)) #define inf 999999999 #define M 152501 using namespace std; int n,m,f[N][21],mx; int main(){ int x,y; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d%d",&x,&y),x++,y++,f[x][0]=max(f[x][0],y),mx=max(mx,y); for(int i=1;i<=mx;i++) f[i][0]=max(f[i][0],max(f[i-1][0],i)); for(int i=1;i<=20;i++){ for(int j=1;j<=mx;j++) f[j][i]=f[f[j][i-1]][i-1]; } for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y);x++;y++; int res=0; for(int j=20;j>=0;j--){ if(f[x][j]<y) res+=1<<j,x=f[x][j]; } x=f[x][0];res++; printf("%d ",x>=y? res:-1); } return 0; }