cf1175E. Minimal Segment Cover[倍增]

傳送門

題意:給出n個線段,然後m次詢問,每次詢問一個區間[L,R],輸出最少需要的線段數能將區間內所有實數點覆蓋
題解:倍增,注意查詢時只有dp[L][i]<R時轉移,dp[L][i]==R時不轉移

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+5;
#define debug(x) cout<<#x<<" is "<<x<<endl;

int dp[maxn][22];

int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    int maxx=0;
    for(int i=1;i<=n;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        maxx=max(maxx,y);
        dp[x][0]=max(dp[x][0],y);
    }
    for(int i=0;i<22;i++){
        for(int j=0;j<=maxx;j++){
            if(j)dp[j][i]=max(dp[j][i],dp[j-1][i]);
            if(i&&dp[j][i-1])dp[j][i]=max(dp[j][i],dp[dp[j][i-1]][i-1]);
        }
    }
    while(m--){
        int x,y;
        scanf("%d%d",&x,&y);
        int ac=0;
        for(int i=21;i>=0;i--){
            if(dp[x][i]<y){
                x=dp[x][i];
                ac+=(1<<i);
            }
        }
        if(x<y){
            ac++;
            x=dp[x][0];
        }
        //debug(x);
        //debug(ac);
        if(x<y)printf("-1\n");
        else printf("%d\n",ac);
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章