codeforces1175E Minimal Segment Cover doubling

Topic Portal

The meaning of problems: gives the n parallel to the x-axis segments, q interrogation times, each time interval of a minimum of several interrogation segments covered, outputting -1 if not covered.

Ideas: first consider greed, must first find all the left point less than $ x $ equal to the largest segment of the right point where, then answer a plus, $ x $ will be moved to the maximum right point, greed continue until the right point greater than $ y $.

  Consider optimization, can be used to speed up the multiplication process, first of all $ f pretreatment with an initial segment [i] [J] $, i-th hop node {2 ^ j} th line to reach the maximum number of right point, and then do some multiplication, always ask, when is the dichotomy jump, every time complexity is $ log (n) $, the total time complexity is $ nlog (n) $.

#pragma GCC optimize (2)
#pragma G++ optimize (2)
#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
#include<cstdio>
#include<vector>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,b,a) for(int i=b;i>=a;i--)
#define clr(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pii pair<int,int >
using namespace std;
typedef long long ll;
const int maxn=500010;
ll rd()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int f[maxn][22],maxx,x,y,n,q;
int fac[22];
int main(){
    fac[0]=1;
    rep(i,1,20){
        fac[i]=2*fac[i-1];
    }
    while(cin>>n>>q){
        clr(f,0);
        rep(i,1,n){
            scanf("%d%d",&x,&y);
            f[x][0]=max(f[x][0],y);
        }
        maxx=500000;
        rep(i,1,maxx){
            f[i][0]=max(f[i][0],f[i-1][0]);
            if(f[i][0]<=i)f[i][0]=0;
        }
//        puts("debug");
        rep(i,1,20){
            rep(j,0,maxx){
                if(f[j][i-1]!=0&&f[f[j][i-1]][i-1]!=0){
                    f[j][i]=f[f[j][i-1]][i-1];
                }
            }
        }
        while(q--){
            scanf("%d%d",&x,&y);
            int r=x;
            int ans=0;
            dep(i,20,0){
                if(f[r][i]==0)continue;
                if(f[r][i]<y){
                    ans+=fac[i];
                    r=f[r][i];
                }
            }
            if(f[r][0]>=y){
                printf("%d\n",ans+1);
            }else{
                puts("-1");
            }
        }
    }
}

 

Guess you like

Origin www.cnblogs.com/mountaink/p/11593946.html