zoukankan      html  css  js  c++  java
  • Codeforces 1175E Minimal Segment Cover

    题意
    (n)条线段,区间为([l_i, r_i]),每次询问([x_i, y_i]),问要被覆盖最少要用多少条线段。

    思路
    (f[i][j])表示以(i)为左端点,用了(2^j)条线段,最远到哪里。
    然后从大到小贪心即可,类似于倍增找LCA的过程。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    #define N 200010
    #define M 500010
    #define D 20
    int n, q;
    int l[N], r[N];
    int f[M][D];
    
    int work(int x, int y) {
    	int ans = 0;
    	for (int i = D - 1; i >= 0; --i) {
    		if (f[x][i] < y) {
    			x = f[x][i];
    			ans |= (1 << i);
    		}
    	}
    	x = f[x][0]; ++ans;
    	if (x < y) ans = -1;
    	return ans;
    }
    
    int main() {
    	while (scanf("%d%d", &n, &q) != EOF) {
    		for (int i = 1; i <= n; ++i) {
    			scanf("%d%d", l + i, r + i);
    			++l[i], ++r[i];
    		}
    		memset(f, 0, sizeof f);
    		for (int i = 1; i <= n; ++i) {
    			f[l[i]][0] = max(f[l[i]][0], r[i]);
    		}
    		for (int i = 1; i < M; ++i) {
    			f[i][0] = max(f[i][0], max(i, f[i - 1][0]));
    			for (int j = 1; j < D; ++j) {  
    				f[i][j] = max(f[i][j], max(f[i][j - 1], f[i - 1][j]));
    			}
    		}
    	
    		for (int j = 1; j < D; ++j) {
    			for (int i = 1; i < M; ++i) {
    				f[i][j] = max(f[i][j], f[f[i][j - 1]][j - 1]);
    			}
    		}	
    		int x, y;
    		while (q--) {
    			scanf("%d%d", &x, &y);
    			++x, ++y;
    			printf("%d
    ", work(x, y));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    ThinkCMF X1.6.0-X2.2.3框架任意内容包含漏洞分析复现
    Apache Solr Velocity模板注入RCE漏洞复现
    WebShell代码分析溯源(十一)
  • 原文地址:https://www.cnblogs.com/Dup4/p/11090212.html
Copyright © 2011-2022 走看看