zoukankan      html  css  js  c++  java
  • CF1555E Boring Segments

    题目传送


    这题比赛的时候想出来了,挺高兴的。


    首先我们把区间按花费排序,然后用一个双指针扫描花费的最大值和最小值,那么在这之间的区间都可以选,而且随着最大值的增加,其最小值的指针必然是单调不减的,因此我们只要用一个数据结构,支持区间修改和查询是否完全被覆盖就行了。

    那必然是线段树了,区间修改+查询最小值,如果大于(0),说明整个区间都被覆盖了。


    这题还有一点,就在于不同区间必须相交,而不是刚好满足(R_i = L_j-1)。解决方法有两个,一是区间取左闭右开,二是区间长度乘以二,即([2L,2R]),我的代码里采用的是第一个。

    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<queue>
    #include<assert.h>
    #include<ctime>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    #define forE(i, x, y) for(int i = head[x], y; ~i && (y = e[i].to); i = e[i].nxt)
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxw = 1e6 + 6;
    //const int maxn = ;
    In ll read()
    {
    	ll ans = 0;
    	char ch = getchar(), las = ' ';
    	while(!isdigit(ch)) las = ch, ch = getchar();
    	while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
    	if(las == '-') ans = -ans;
    	return ans;
    }
    In void write(ll x)
    {
    	if(x < 0) x = -x, putchar('-');
    	if(x >= 10) write(x / 10);
    	putchar(x % 10 + '0');
    }
    In void MYFILE()
    {
    #ifndef mrclr
    	freopen(".in", "r", stdin);
    	freopen(".out", "w", stdout);
    #endif
    }
    
    int n, m;
    struct Node
    {
    	int L, R;
    };
    vector<Node> v[maxw];
    
    int l[maxw << 2], r[maxw << 2], Min[maxw << 2], lzy[maxw << 2];
    In void build(int L, int R, int now)
    {
    	l[now] = L, r[now] = R;
    	if(L == R) return;
    	int mid = (L + R) >> 1;
    	build(L, mid, now << 1), build(mid + 1, R, now << 1 | 1);
    }
    In void pushdown(int now)
    {
    	if(lzy[now])
    	{
    		lzy[now << 1] += lzy[now];
    		Min[now << 1] += lzy[now];
    		lzy[now << 1 | 1] += lzy[now];
    		Min[now << 1 | 1] += lzy[now];
    		lzy[now] = 0;
    	}
    }
    In void update(int L, int R, int now, int d)
    {
    	if(l[now] == L && r[now] == R)
    	{
    		lzy[now] += d;
    		Min[now] += d;
    		return;
    	}
    	pushdown(now);
    	int mid = (l[now] + r[now]) >> 1;
    	if(R <= mid) update(L, R, now << 1, d);
    	else if(L > mid) update(L, R, now << 1 | 1, d);
    	else update(L, mid, now << 1, d), update(mid + 1, R, now << 1 | 1, d);
    	Min[now] = min(Min[now << 1], Min[now << 1 | 1]);
    }
    
    int main()
    {
    //	MYFILE();
    	n = read(), m = read();
    	build(1, m - 1, 1);
    	int MIN = INF, MAX = 0;
    	for(int i = 1; i <= n; ++i)
    	{
    		int L = read(), R = read() - 1, w = read();
    		v[w].push_back((Node){L, R});
    		MIN = min(MIN, w);
    		MAX = max(MAX, w);
    	}
    	int ans = INF;
    	for(int i = MIN, j = MIN; i <= MAX; ++i)
    	{
    		if(v[i].size() == 0) continue;
    		for(auto x : v[i])
    		{
    			int L = x.L, R = x.R;
    			update(L, R, 1, 1);
    		}
    		while(j <= i)
    		{
    			if(v[j].size() == 0) {j++; continue;}
    			for(auto x : v[j])
    			{
    				int L = x.L, R = x.R;
    				update(L, R, 1, -1);
    			}
    			if(Min[1] == 0)
    			{
    				for(auto x : v[j])
    				{
    					int L = x.L, R = x.R;
    					update(L, R, 1, 1);
    				}
    				break;
    			}
    			j++;
    		}
    		if(Min[1] > 0) ans = min(ans, i - j);
    	}
    	write(ans), enter;
    	return 0;
    }
    ···
  • 相关阅读:
    Hive join操作优化
    php中 date 函数中的格式参数
    Mysql分表之后的聚合统计
    使用Elasticsearch-Dump工具复制ES库
    Json Path 语法详解(Java)
    Json Path 语法
    关于qt5.2~qt5.8的下载地址
    RTL8812AU双频无线网卡在ubuntu19和20上的驱动安装
    使用vscode对threejs的本地调试
    ThreeJS中创建文字的几种方法
  • 原文地址:https://www.cnblogs.com/mrclr/p/15086707.html
Copyright © 2011-2022 走看看