• Luogu P1250 种树


    题目大意

      有(n)个格子((1 leq n leq 30000)),每个格子可以种(1)棵树。现在给你(h)个要求((1 leq h leq 5000)),格式为(oxed{l_i ext{ } r_i ext{ } t_i}),表示要求格子区间([l_i, r_i])中至少种(t_i)棵树((1 leq l_i leq r_i leq n)(0 leq t_i leq r_i - l_i + 1))。问你最少要种多少棵树才能满足所有要求。

    题解

      很显然的贪心策略,每次尽可能靠近(r_i)种树。
      我们可以用树状数组来查询一段区间内有多少棵树,并且修改每个格子(对应种树)。
      如果朴素枚举哪些格子没种树,虽然能ac,但显然不够优。我们可以用并查集来维护对于每个点(i),从(i)开始往(1)找,第(1)个没有种树的格子的位置(p[i])
      初始化显然为(p[i] = i),然后对于每个操作(i),我们从(r_i)开始枚举没有种树的格子(j),显然刚开始是让(j = p[r_i])
      我们如何确定下一个没有种树的格子呢?其实我们可以直接使(p[j] = p[j - 1]),然后使(j = p[j])即可,显然这是可行的。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    #define MAX_N (30000 + 5)
    #define MAX_H (5000 + 5)
    
    #define lowbit(x) ((x) & -(x))
    
    using namespace std;
    
    struct Node
    {
    	int l, r, t;
    };
    
    inline bool cmp(Node a, Node b)
    {
    	if (a.r != b.r) return a.r < b.r;
    	return a.l < b.l;
    };
    
    int n, h;
    Node a[MAX_H];
    int s[MAX_N];
    int p[MAX_N];
    
    int GetRoot(int x)
    {
    	if (x == p[x]) return x;
    	return p[x] = GetRoot(p[x]);
    }
    
    void Modify(int x)
    {
    	while (x <= n) ++s[x], x += lowbit(x);
    	return;
    }
    
    int Query(int l, int r)
    {
    	--l;
    	int sum = 0;
    	while (r) sum += s[r], r -= lowbit(r);
    	while (l) sum -= s[l], l -= lowbit(l);
    	return sum;
    }
    
    int main()
    {
    	scanf("%d%d", &n, &h);
    	for (int i = 1; i <= n; ++i)
    	{
    		p[i] = i;
    	}
    	for (int i = 1; i <= h; ++i)
    	{
    		scanf("%d%d%d", &a[i].l, &a[i].r, &a[i].t);
    	}
    	sort(a + 1, a + h + 1, cmp);
    	int cnt;
    	for (int i = 1; i <= h; ++i)
    	{
    		cnt = Query(a[i].l, a[i].r);
    		for (int j = GetRoot(a[i].r); cnt < a[i].t; j = GetRoot(j))
    		{
    			Modify(j);
    			++cnt;
    			p[j] = GetRoot(j - 1);
    		}
    	}
    	printf("%d", Query(1, n));
    	return 0;
    }
    
  • 相关阅读:
    彻底理解 Python 生成器
    Windows上虚拟环境的安装及使用
    github怎么绑定自己的域名
    解决ImportError: cannot import name HTTPSHandler
    服务器(Linux) 安装python3
    函数的参数(必选,默认,可变,关键字)
    python 异常处理(try...finally...和with...as 方法)
    LeetCode 33. 搜索旋转排序数组 | Python
    LeetCode 46. 全排列
    LeetCode 面试题51. 数组中的逆序对
  • 原文地址:https://www.cnblogs.com/kcn999/p/11358294.html
Copyright © 2020-2023  润新知