G - 01Sequence dsu菊花树 dsu枚举i

//这个是构造题。。用dsu 来进行枚举i的🔥超爱的 感觉dsu又雄起了。。。
// 他要求[l,r]区间要有x个1 。。可以用树状数组来查询 之前已经填充的量。然后
// 这里有个贪心思想就是 能填右边的就右边先填。。因为右边的1 可能被后面的区间覆盖到。。也就是可以多贡献几次。
// 这样反过来说 1就会尽可能少。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll __int128_t
#define ar array<int, 2>
#define arr array<int, 3>
int  n, m, k, inf = 1LL << 61, mod = 998244353;// 1e9+7;
const int N = 5e5 + 50;
int tr[N], K;
void add(int x, int v) {
	while (x <= K) {//这个K变量是开放的。。是个隐患。。
		tr[x] += v, x += x & (-x);
	}
}
int query(int x) {
	int s = 0;
	while (x) {
		s += tr[x], x -= x & (-x);
	}
	return s;
}
struct DSU {
	std::vector<int> f, sz;
	DSU(int n) : f(n + 1), sz(n + 1, 1) { std::iota(f.begin(), f.end(), 0); }
	int leader(int x) {
		if (x == f[x]) return x;
		f[x] = leader(f[x]);
		//sz[f[x]] += sz[x];//一个dfs后序位置。。实际上已经是带权并查集的合并了。
		//sz[x] = 0;
		return f[x];
	}
	bool same(int x, int y) { return leader(x) == leader(y); }
	bool merge(int x, int y) { //这个是把y并到x的子树上。。有方向的。细节。
		x = leader(x);
		y = leader(y);
		if (x == y)
			return false;
		sz[x] += sz[y];
		//sz[y]=0;
		f[y] = x;
		return true;
	}
	int size(int x) { return sz[leader(x)]; }
};

void solve() {
	cin >> n >> m;
	K = n;//这个k是我书树状数组的max。。树状数组还没有找到合适的封闭的模版 泪目。
	arr a[m];
	for (auto&[y, x, z] : a)//我们这里把y放在第一权重. 这样排序 就不需要自定义规则
		cin >> x >> y >> z;
	sort(a, a + m);

	DSU uf(n);
	vector<int>ans(n + 1);
	for (auto[y, x, z] : a) {
		int t = query(y) - query(x - 1);
		if (t >= z)
			continue;
		z -= t;
		for (int i = uf.leader(y); z--; i = uf.leader(i)) {
			add(i, 1);
			ans[i] = 1;
			uf.merge(i - 1, i);//细节: 这里的合并是有方向的  也就是不能改变i-1 和i的位置 。我们要把f[i]=i-1这样的。往前走
		}
	}

	for (int i = 1; i <= n; ++i)
		cout << ans[i] << ' ';
};








signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(15);
#ifdef DEBUG
	freopen("../1.in", "r", stdin);
#endif
	//init_f();
	//init();
	//expr();
	// int T; cin >> T; while(T--)
	solve();
	return 0;
}



这里dsu来枚举i 的靠谱性。dsu本质上就是 树。。而路径压缩 本质上就是改变数结构 变成菊花树
这题是特化了 它是一个链 。
然后我们又规定了merge的方向 以下标i小的为根。。
所以他每个联通的部分全部🔥会指联通块内 下标最小的位置 以之为根。所以。稳定性ok的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值