首页 > 其他分享 >[ABC216G] 01Sequence

[ABC216G] 01Sequence

时间:2023-12-31 21:33:05浏览次数:28  
标签:set int ABC216G void FL BIT 01Sequence

题目链接

很显然,按照右端点从小到大排序,对于每段区间尽量地贪心放在靠右的位置即可。

中间用 std::set 维护当前还是 \(0\) 的位置,以及树状数组维护区间 \(1\) 的个数。

点击查看代码
#include <bits/stdc++.h>
#define FL(i, a, b) for(int i = (a); i <= (b); ++i)
#define FR(i, a, b) for(int i = (a); i >= (b); --i)
constexpr int N = 2e5 + 10;
struct D{int l, r, x;} d[N];
int n, m, a[N];
std::set<int> s;
struct BIT{
	int n; int c[N];
	BIT(int x = 0) : n(x){}
	void resize(int x){FL(i, n + 1, x) c[i] = 0; n = x;}
	void clear(){FL(i, 1, n) c[i] = 0;}
	void add(int x, int v = 1){
		for(; x <= n; x += x & -x) c[x] += v;
	}
	int ask(int x, int ret = 0){
		for(; x; x -= x & -x) ret += c[x];
		return ret;
	}
} b;
int main(){
    scanf("%d%d", &n, &m), b.resize(n);
    FL(i, 1, n) s.emplace(i);
    FL(i, 1, m) scanf("%d%d%d", &d[i].l, &d[i].r, &d[i].x);
    std::sort(d + 1, d + m + 1, [&](D x, D y){return x.r < y.r;});
    FL(i, 1, m){
        auto it = s.upper_bound(d[i].r);
        while(it != s.begin() && b.ask(d[i].r) - b.ask(d[i].l - 1) < d[i].x){
            a[*--it] = 1, b.add(*it);
            s.erase(it), it = s.upper_bound(d[i].r);
        }
    }
    FL(i, 1, n) printf("%d%c", a[i], " \n"[i == n]);
    return 0;
}

标签:set,int,ABC216G,void,FL,BIT,01Sequence
From: https://www.cnblogs.com/zac2010/p/17938022

相关文章

  • [ABC216G] 01Sequence 题解
    01Sequence题目大意构造一个满足\(m\)个形如\((l,r,x)\)的限制条件的\(01\)序列,其中\((l,r,x)\)表示区间\([l,r]\)的和不小于\(x\),你需要保证序列中\(1\)的个数最小。思路分析贪心的想,如果我们将限制按右端点排序,那么当遍历到一个区间,发现现有的和不满足限制条件......
  • ABC216G
    将区间按照右端点排序,贪心的往最右边填\(1\),不难发现这样一定是正确的。感性理解一下就是越往右的位置对于后面的区间贡献越大。而且每个点最多只会被放置一个\(1\),所以我们可以暴力的找到下一个可以填的位置,并填入\(1\),可以使用线段树维护,复杂度是\(\mathcal{O}(n\logn)\)......