• CF1175E Minimal Segment Cover


    一个很妙的操作,求出每个点通过一条边可以向右边覆盖的最远距离,然后倍增。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    #define R register
    #define LL long long
    const int inf = 0x3f3f3f3f;
    const int MAXN = 5e5 + 10;
    
    inline int read() {
    	char a = getchar(); int x = 0,f = 1;
    	for(; a > '9' || a < '0'; a = getchar()) if(a == '-') f = -1;
    	for(; a >= '0' && a <= '9' ;a = getchar()) x = x * 10 + a - '0';
    	return x * f;
    }
    
    int n, m, D;
    int mx[MAXN];
    int dp[MAXN][20];
    
    int main() {
    	//freopen(".in","r",stdin);
    	//freopen(".out","w",stdout);
    	n = read(); m = read();
    	for(R int i = 1; i <= n; i++) {
    		int x = read(), y = read();
    		mx[x] = max(mx[x], y);
    		D = max(D, y);
    	}
    	for(R int i = 1; i <= D; i++) mx[i] = max(mx[i], mx[i - 1]);
    	//for(R int i = 1; i <= D; i++) printf("%d ", mx[i]);
    	for(R int i = 0; i <= D; i++) dp[i][0] = mx[i];
    	for(R int j = 1; j < 20; j++)
    		for(R int i = 0; i <= D; i++)
    			dp[i][j] = dp[dp[i][j - 1]][j - 1];
    	while(m--) {
    		int l = read(), r = read();
    		int ans = 0;
    		for(R int i = 19 ; i >= 0 ; i --)
    			if(dp[l][i] < r) {
    				ans += (1 << i);
    				l = dp[l][i];
    			}
    		if(mx[l] >= r) printf("%d
    ", ans + 1);
    		else printf("-1
    ");
    	}
    	return 0;	
    }
    
  • 相关阅读:
    目录-富爸爸穷爸爸
    目录-高效能人士的七个习惯(精华版)
    目录-卓有成效的管理者
    计算机网络自顶向下方法目录
    计算机网络_第7版_谢希仁_目录
    计算机网络各层协议
    TCP_IP详解卷一目录
    http 权威指南 目录
    Redis 知识体系
    Apache Commons 列表
  • 原文地址:https://www.cnblogs.com/clover4/p/12896244.html
Copyright © 2020-2023  润新知